Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
lenak25 committed Sep 4, 2018
2 parents 6d40a3b + 47f373f commit 46382a2
Show file tree
Hide file tree
Showing 20 changed files with 435 additions and 71 deletions.
42 changes: 39 additions & 3 deletions catalyst/api.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,39 @@ def cancel_order(order_param, symbol=None, params={}):
"""


def get_orderbook(asset, order_type='all', limit=None):
"""Get the order book of asset.exchange.
Parameters
----------
asset : Asset
The asset .
order_type : str, optional
limit : int, optional
"""


def get_open_orders(asset=None):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed and not None, return only the open orders for the given
asset instead of all open orders.
Returns
-------
open_orders : dict[list[Order]] or list[Order]
If no asset is passed this will return a dict mapping Assets
to a list containing all the open orders for the asset.
If an asset is passed then this will return a list of the open
orders for this asset.
"""


def continuous_future(root_symbol_str, offset=0, roll='volume',
adjustment='mul'):
"""Create a specifier for a continuous contract.
Expand Down Expand Up @@ -213,7 +246,8 @@ def get_environment(field='platform'):
"""


def get_order(order_id, asset_or_symbol=None, return_price=False):
def get_order(order_id, asset_or_symbol=None,
return_price=False, params={}):
"""Lookup an order based on the order id returned from one of the
order functions.
Expand All @@ -223,8 +257,10 @@ def get_order(order_id, asset_or_symbol=None, return_price=False):
The unique identifier for the order.
asset_or_symbol: Asset or str
The asset or the tradingPair symbol of the order.
return_price: bool
get the trading price in addition to the order
return_price: bool
get the trading price in addition to the order
params: dict, optional
Extra parameters to pass to the exchange
Returns
-------
Expand Down
5 changes: 5 additions & 0 deletions catalyst/data/minute_bars.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,11 @@ def get_value(self, sid, dt, field):
self._last_get_value_dt_value = dt.value
self._last_get_value_dt_position = minute_pos

# a patch for requesting non existing time frames
# due to the different candles labeling + wrong start dates
if minute_pos < 0:
return np.nan

try:
value = self._open_minute_file(field, sid)[minute_pos]
except IndexError:
Expand Down
43 changes: 30 additions & 13 deletions catalyst/exchange/ccxt/ccxt_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
poloniex=ccxt.poloniex,
bitmex=ccxt.bitmex,
gdax=ccxt.gdax,
huobipro=ccxt.huobipro,
okex=ccxt.okex,
hitbtc=ccxt.hitbtc2,
kucoin=ccxt.kucoin,
)


Expand Down Expand Up @@ -454,13 +458,21 @@ def get_candles(self, freq, assets, bar_count=1, start_dt=None,

candles = dict()
for index, asset in enumerate(assets):
ohlcvs = self.api.fetch_ohlcv(
symbol=symbols[index],
timeframe=timeframe,
since=since,
limit=bar_count,
params={}
)
try:
ohlcvs = self.api.fetch_ohlcv(
symbol=symbols[index],
timeframe=timeframe,
since=since,
limit=bar_count,
params={}
)
except (ExchangeError, NetworkError) as e:
log.warn(
'unable to fetch {} ohlcv: {}'.format(
asset, e
)
)
raise ExchangeRequestError(error=e)

candles[asset] = []
for ohlcv in ohlcvs:
Expand Down Expand Up @@ -897,7 +909,6 @@ def create_order(self, asset, amount, is_buy, style):
amount
)
)

adj_amount = round(abs(amount), asset.decimals)
prec_amount = self.api.amount_to_precision(symbol, adj_amount)
before_order_dt = pd.Timestamp.utcnow()
Expand Down Expand Up @@ -1140,7 +1151,8 @@ def process_order(self, order):
order.broker_order_id = ', '.join([t['id'] for t in trades])
return transactions

def get_order(self, order_id, asset_or_symbol=None, return_price=False):
def get_order(self, order_id, asset_or_symbol=None,
return_price=False, params={}):
"""Lookup an order based on the order id returned from one of the
order functions.
Expand All @@ -1152,6 +1164,8 @@ def get_order(self, order_id, asset_or_symbol=None, return_price=False):
The asset or the tradingPair symbol of the order.
return_price: bool
get the trading price in addition to the order
params: dict, optional
Extra parameters to pass to the exchange
Returns
-------
Expand All @@ -1168,7 +1182,9 @@ def get_order(self, order_id, asset_or_symbol=None, return_price=False):
try:
symbol = self.get_symbol(asset_or_symbol) \
if asset_or_symbol is not None else None
order_status = self.api.fetch_order(id=order_id, symbol=symbol)
order_status = self.api.fetch_order(id=order_id,
symbol=symbol,
params=params)
order, executed_price = self._create_order(order_status)

if return_price:
Expand Down Expand Up @@ -1301,10 +1317,11 @@ def get_orderbook(self, asset, order_type='all', limit=None):
order_types = ['bids', 'asks'] if order_type == 'all' else [order_type]
result = dict(last_traded=from_ms_timestamp(order_book['timestamp']))
for index, order_type in enumerate(order_types):
if limit is not None and index > limit - 1:
break

result[order_type] = []

if limit is not None and len(order_book[order_type]) > limit:
order_book[order_type] = order_book[order_type][:limit]

for entry in order_book[order_type]:
result[order_type].append(dict(
rate=float(entry[0]),
Expand Down
7 changes: 6 additions & 1 deletion catalyst/exchange/exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,8 @@ def get_open_orders(self, asset):
pass

@abstractmethod
def get_order(self, order_id, symbol_or_asset=None):
def get_order(self, order_id, symbol_or_asset=None,
return_price=False, params={}):
"""Lookup an order based on the order id returned from one of the
order functions.
Expand All @@ -925,6 +926,10 @@ def get_order(self, order_id, symbol_or_asset=None):
The unique identifier for the order.
symbol_or_asset: str|TradingPair
The catalyst symbol, some exchanges need this
return_price: bool
get the trading price in addition to the order
params: dict, optional
Extra parameters to pass to the exchange
Returns
-------
Expand Down
39 changes: 37 additions & 2 deletions catalyst/exchange/exchange_algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def __init__(self, *args, **kwargs):
get_spot_value_attempts=5,
get_history_window_attempts=5,
retry_sleeptime=5,
get_orderbook_attempts=5,
)

self.blotter = ExchangeBlotter(
Expand Down Expand Up @@ -1085,7 +1086,8 @@ def get_open_orders(self, asset=None):
)

@api_method
def get_order(self, order_id, asset_or_symbol=None, return_price=False):
def get_order(self, order_id, asset_or_symbol=None,
return_price=False, params={}):
"""Lookup an order based on the order id returned from one of the
order functions.
Expand All @@ -1097,6 +1099,8 @@ def get_order(self, order_id, asset_or_symbol=None, return_price=False):
The asset or the tradingPair symbol of the order.
return_price: bool
get the trading price in addition to the order
params: dict, optional
Extra parameters to pass to the exchange
Returns
-------
Expand All @@ -1113,7 +1117,7 @@ def get_order(self, order_id, asset_or_symbol=None, return_price=False):
sleeptime=self.attempts['retry_sleeptime'],
retry_exceptions=(ExchangeRequestError,),
cleanup=lambda: log.warn('Fetching orders again.'),
args=(order_id, asset_or_symbol, return_price)
args=(order_id, asset_or_symbol, return_price, params)
)

@api_method
Expand Down Expand Up @@ -1150,3 +1154,34 @@ def cancel_order(self, order_param, symbol=None, params={}):
self.blotter.cancel(order_id)
else:
self.blotter.cancel(order_id)

def _get_orderbook(self, asset, order_type='all', limit=None):
exchange = self.exchanges[asset.exchange]
return exchange.get_orderbook(asset, order_type, limit)

@api_method
def get_orderbook(self, asset, order_type='all', limit=None):
"""
Retrieve the orderbook for the given trading pair.
Parameters
----------
asset: TradingPair
order_type: str
The type of orders: bid, ask or all
limit: int
Returns
-------
list[dict[str, float]
"""
return retry(
action=self._get_orderbook,
attempts=self.attempts['get_orderbook_attempts'],
sleeptime=self.attempts['retry_sleeptime'],
retry_exceptions=(ExchangeRequestError,),
cleanup=lambda: log.warn('Requesting order book again'),
args=(asset, order_type, limit),
)
4 changes: 4 additions & 0 deletions catalyst/exchange/exchange_data_portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,10 @@ def get_exchange_spot_value(self,
dt = dt.floor('1D')
else:
dt = dt.floor('1 min')
# In order to align with the crypto left
# bounded candles, we request the candle of the previous timestamp
# (do not include the current minute)
dt = dt - datetime.timedelta(minutes=1)

if AUTO_INGEST:
try:
Expand Down
21 changes: 21 additions & 0 deletions catalyst/support/issue_420.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from catalyst.api import symbol
from catalyst.utils.run_algo import run_algorithm


def initialize(context):
pass


def handle_data(context, data):
data.history(symbol("DASH_BTC"), ['close'],
bar_count=200, frequency='15T')


run_algorithm(initialize=lambda ctx: True,
handle_data=handle_data,
exchange_name='poloniex',
quote_currency='usd',
algo_namespace='issue-420',
live=True,
data_frequency='daily',
capital_base=3000)
3 changes: 3 additions & 0 deletions docs/source/appendix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ Orders

.. autofunction:: catalyst.api.cancel_order

.. autofunction:: catalyst.api.get_orderbook


Order Cancellation Policies
'''''''''''''''''''''''''''

Expand Down
10 changes: 5 additions & 5 deletions docs/source/beginner-tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ A few comments on the code above:
you will see that in most cases, the performance is either worse than the
price of the asset, or you are overfitting to one specific case. As we said
at the beginning of this section, this strategy is probably not used by any
serious trader anymore, but its educational purpose.
serious trader anymore, but it has an educational purpose.

Although it might not be directly apparent, the power of ``history()``
(pun intended) can not be under-estimated as most algorithms make use of
Expand Down Expand Up @@ -16465,7 +16465,7 @@ PyCharm IDE
~~~~~~~~~~~

PyCharm is an Integrated Development Environment (IDE) used in computer
programming, specifically for the Python language. It streamlines the continuos
programming, specifically for the Python language. It streamlines the continuous
development of Python code, and among other things includes a debugger that
comes in handy to see the inner workings of Catalyst, and your trading
algorithms.
Expand All @@ -16478,12 +16478,12 @@ There is a free and open-source **Community** version.
Setup
^^^^^

1. When creating a new project in PyCharm, right under you specify the Location,
1. When creating a new project in PyCharm, right under where you specify the Location,
click on **Project Interpreter** to display a drop down menu

2. Select **Existing interpreter**, click the gear box right next to it and
select 'add local'. Depending on your installation, select either
"*Virtual Environemnt*" or "*Conda Environment" and click the '...' button to
"*Virtual Environment*" or "*Conda Environment" and click the '...' button to
navigate to your catalyst env and select the Python binary file:
``bin/python`` for Linux/MacOS installations or 'python.exe' for Windows
installs (for example: 'C:\\Users\\user\\Anaconda2\\envs\\catalyst\\python.exe').
Expand All @@ -16509,7 +16509,7 @@ Next steps
~~~~~~~~~~

We hope that this tutorial gave you a little insight into the
architecture, API, and features of Catalyst. For next steps, check
architecture, API, and features of Catalyst. For your next step, check
out some of the other :doc:`example algorithms<example-algos>`.

Feel free to ask questions on the ``#catalyst_dev`` channel of our
Expand Down
47 changes: 47 additions & 0 deletions docs/source/development-guidelines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,53 @@ If you want to contribute to the codebase of Catalyst, familiarize yourself with

.. image:: https://camo.githubusercontent.com/9bde6fb64a9542a572e0e2017cbb58d9d2c440ac/687474703a2f2f6e7669652e636f6d2f696d672f6769742d6d6f64656c4032782e706e67

Style Guide & Running Tests
---------------------------

We use `flake8`__ for checking style requirements and `nosetests`__ to run Catalyst tests. Our `continuous integration`__ tool will run these commands.

__ http://flake8.pycqa.org/en/latest/
__ http://nose.readthedocs.io/en/latest/
__ https://en.wikipedia.org/wiki/Continuous_integration

Before submitting patches or pull requests, please ensure that your changes pass when running:

.. code-block:: bash
$ flake8 catalyst tests
In order to run tests locally, you'll need to install several libraries
(one of them is TA-lib, so make sure you have it installed following `these instructions`__ before continuing).

__ https://mrjbq7.github.io/ta-lib/install.html

.. code-block:: bash
$ pip install -r ./etc/requirements.txt
$ pip install -r ./etc/requirements_dev.txt
$ pip install -r ./etc/requirements_blaze.txt
$ pip install -r ./etc/requirements_talib.txt
$ pip install -e .
You should now be free to run tests:

.. code-block:: bash
$ cd tests && nosetests
Continuous Integration
----------------------

We use `Travis CI`__ for Linux-64 bit builds.

.. note::

We do not currently have CI for OSX-64 bit builds or Windows-64 bit builds.

__ https://travis-ci.com/enigmampc/catalyst


Contributing to the Docs
------------------------

Expand Down
Loading

0 comments on commit 46382a2

Please sign in to comment.