Minor fixes

This commit is contained in:
Frederic Fortier
2017-08-18 02:03:00 -04:00
parent 51cda7b2d4
commit 37a07e03e5
4 changed files with 61 additions and 49 deletions
+3 -3
View File
@@ -18,7 +18,7 @@ log = Logger('buy_and_hold_live')
def initialize(context):
log.info('initializing algo')
context.asset = symbol('eos_usd')
context.asset = symbol('eos_btc')
context.TARGET_HODL_RATIO = 0.8
context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
@@ -53,7 +53,7 @@ def handle_data(context, data):
# Check if still buying and could (approximately) afford another purchase
if context.is_buying and cash > price:
# Place order to make position in asset equal to target_hodl_value
order(context.asset, 1, limit_price=price + 1.1)
order(context.asset, 1, limit_price=price * 1.1)
# This works
# order_target_value(
# context.asset,
@@ -79,7 +79,7 @@ exchange_conn = dict(
name='bitfinex',
key='',
secret=b'',
base_currency='usd'
base_currency='btc'
)
run_algorithm(
initialize=initialize,
+19 -11
View File
@@ -193,7 +193,8 @@ class Bitfinex(Exchange):
portfolio.cash = float(base_position['available'])
if portfolio.positions:
tickers = self.tickers(portfolio.positions.keys())
assets = portfolio.positions.keys()
tickers = self.tickers(assets)
portfolio.positions_value = 0.0
for ticker in tickers:
# TODO: convert if the position is not in the base currency
@@ -209,8 +210,9 @@ class Bitfinex(Exchange):
@property
def portfolio(self):
"""
TODO: I'm not sure how that's used yet
:return:
Return the Portfolio
:return:
"""
if self.store.portfolio is None:
portfolio = ExchangePortfolio(
@@ -402,18 +404,16 @@ class Bitfinex(Exchange):
:func:`catalyst.api.order_value`
:func:`catalyst.api.order_percent`
"""
log.debug(
'ordering {amount} {symbol} {style}'.format(
amount=amount,
symbol=asset.symbol,
style=style
)
)
if amount == 0:
log.warn('skipping order amount of 0')
return None
base_currency = asset.symbol.split('_')[1]
if base_currency.lower() != self.base_currency.lower():
raise NotImplementedError(
'Currency pairs must share their base with the exchange.'
)
is_buy = (amount > 0)
if isinstance(style, MarketOrder):
@@ -432,6 +432,14 @@ class Bitfinex(Exchange):
else:
raise NotImplementedError('%s orders not available' % style)
log.debug(
'ordering {amount} {symbol} for {price}'.format(
amount=amount,
symbol=asset.symbol,
price=price
)
)
exchange_symbol = self.get_symbol(asset)
req = dict(
symbol=exchange_symbol,
+1 -1
View File
@@ -64,8 +64,8 @@ class ExchangeClock(object):
server_time = current_time.floor('1 min')
if self._last_emit is None or server_time > self._last_emit:
log.debug('emitting minutely bar: {}'.format(server_time))
print 'emitting bar %s' % server_time
self._last_emit = server_time
yield server_time, BAR
+38 -34
View File
@@ -3,36 +3,33 @@ The purpose of this document is to allow project contributors navigate
through the ongoing live trading implementation.
<h2>Components</h2>
At a high level the following components have been implemented to coerce
At a high level, the following components have been implemented to coerce
zipline into live trading.
<h3>Exchange</h3>
*catalyst/exchange*
Exchange is a new package which introduces the concept of cryptocurrency
exchanges to zipline. The package contains all new component
implementations adapted to characteristics of exchanges.
Exchange is a new package introducing cryptocurrency
exchanges to zipline. The package contains mostly new implementations
of existing components, adapted to characteristics of exchanges.
Here are some key characteristics which makes exchanges different from
equity and futures currently implemented in zipline.
Here are some key characteristics which make cryptocurrency exchanges
exchanges different compared to equity brokers.
* They trade around the clock.
* Currency symbols are inconsistent across exchanges.
* They trade currency pairs, i.e. the base currency is not always be USD.
This is a significant departure from the equity market. Additional
business logic will be required both to assess performance and
manage trades.
* The cryptocurrency market being relatively immature, there are still
significant price arbitrage opportunities between exchanges.
In contrast with the equity markets, trader usually trade directly
against an exchange (as oppose to using a broker). Consequently,
to extract maximum alpha, the platform should not only support
multiple exchanges, but also multiple exchanges per algorithm.
* They trade currency pairs (i.e. the base currency is not always be USD).
This is a paradigm shift in context of zipline. Additional
business logic will be required to manage the portfolio data and orders.
* The price of a single asset might vary across exchanges. This means
arbitrage opportunities. Consequently, to extract maximum alpha, the
platform should not only support multiple exchanges, but also multiple
exchanges per algorithm.
* The fee model is usually more complex than that of an equity broker.
It can vary drastically between exchanges.
* There are no splits, mergers, etc to worry about.
* Their order book is publicly available, the platform should access to
it as it can be used to drastically reduce slippage.
* There are no splits, mergers, etc. to worry about.
* A complete order book is usually available, the platform should
offer access to it order to help traders reduce slippage.
<h3>New Components</h3>
These components of the exchange package were added to the zipline
@@ -42,7 +39,7 @@ sources.
*catalyst/exchange/exchange.py*
Abstract class which acts an interface for the implementation of
Abstract class which acts as an interface for the implementation of
various exchanges. It also contains logic common to all exchanges.
<h4>Bitfinex</h4>
@@ -59,14 +56,20 @@ Extends the zipline DataPortal to route spot data to the exchange.
This is critical because it allows the algoritm to request data in
real-time.
For example, `data.current(asset, 'price')` retrieves the current price of the asset, not the price at the time
of yielding the bar this is critical to minimize slippage.
For example, `data.current(asset, 'price')` retrieves the current price
of the asset, not the price at the time of yielding the bar this
is critical to minimize slippage.
At the time of writing, it only supports spot data but I believe that
it should be extended to historical data as well. Some exchanges
have better historical data APIs than others. This will need to
be considered during each individual implementation.
<h4>ExchangeClock</h4>
*catalyst/exchange/exchange_clock.py*
An implementation to the zipline Clock which runs 24/7. It yeilds a
An implementation to the zipline Clock which runs 24/7. It yields a
bar every minute.
<h4>AssetFinderExchange</h4>
@@ -76,15 +79,14 @@ bar every minute.
An alternate implementation of AssetFinder which locates each asset
against the exchanges instead of bundle databases.
For example, `symbol('eth_usd')` retrieves an Asset object against the exchange as opposed to querying
a database of equities.
For example, `symbol('eth_usd')` should return an Ethereum/USD asset
regardless of currency notation of the target exchange.
I have created a dictionary of currencies for the Bitfinex exchange.
The primary goal is to standardize the symbol notation across exchanges.
Here is a snippet of the file.
To acheive this, I have created a dictionary of currencies for the
Bitfinex exchange. Here is what it looks like.
* Each key represents the exchange specific symbol.
* The symbol attribute represents the standard symbol which
should be common across exchanges for the given currency.
* The symbol attribute represents the abstract symbol common across
all exchanges for the given currency.
* The start_date attribute should correspond to its first trading day
on the exchange.
@@ -132,13 +134,15 @@ business logic to enable live trading.
The run_algorithm interface is an entry point to execute an
algorithm in zipline. This component was already modified for
the catalyst concurrency bundles. I added conditional logic to
which should not break any of the existing backtesting implementations.
the catalyst concurrency bundles. I added conditional logic
which should not interfere with backtesting.
At a high-level the run_algorithm method now contains two additional
In a nutshell, the run_algorithm method now contains three additional
parameters:
* live: If True, zipline will attempt to trade live. If False or not
specified, it will run a backtest as normal.
* algo_namespace: An arbitrary namespace for the current algorithm.
It will be used to persist data between runs.
* exchange_conn: A dictionary containing the attributes required
to instantiate an exchange. Here is an example for Bitfinex:
@@ -189,7 +193,7 @@ cost basis would correspond to all positions, not just those
initiated by the algorithm.
* It would not be possible impose trading limits on algorithms.
It follow that Portfolio metrics should be calculated using a strategic
It follows that Portfolio metrics should be calculated using a strategic
combination of the exchange data and algorithm activity. While tracking
the activity of an algorithm works well in backtesting, it is more
challenging during live trading. A live algorithm might run over