mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-10 08:02:22 +08:00
Minor fixes
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user