Merge branch 'master' into develop

This commit is contained in:
Victor Grau Serrat
2017-11-28 11:23:31 -07:00
5 changed files with 191 additions and 43 deletions
+10 -15
View File
@@ -15,15 +15,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import pandas as pd
import matplotlib.pyplot as plt
from catalyst import run_algorithm
from catalyst.api import (
order_target_value,
symbol,
record,
cancel_order,
get_open_orders,
)
from catalyst.api import (order_target_value, symbol, record,
cancel_order, get_open_orders, )
def initialize(context):
@@ -78,15 +74,14 @@ def handle_data(context, data):
def analyze(context=None, results=None):
import matplotlib.pyplot as plt
# Plot the portfolio and asset data.
ax1 = plt.subplot(611)
results[['portfolio_value']].plot(ax=ax1)
ax1.set_ylabel('Portfolio Value (USD)')
ax1.set_ylabel('Portfolio\nValue\n(USD)')
ax2 = plt.subplot(612, sharex=ax1)
ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME))
ax2.set_ylabel('{asset}\n(USD)'.format(asset=context.ASSET_NAME))
results[['price']].plot(ax=ax2)
trans = results.ix[[t != [] for t in results.transactions]]
@@ -126,11 +121,11 @@ def analyze(context=None, results=None):
'algorithm',
'benchmark',
]].plot(ax=ax5)
ax5.set_ylabel('Percent Change')
ax5.set_ylabel('Percent\nChange')
ax6 = plt.subplot(616, sharex=ax1)
results[['volume']].plot(ax=ax6)
ax6.set_ylabel('Volume (mCoins/5min)')
ax6.set_ylabel('Volume')
plt.legend(loc=3)
@@ -142,13 +137,13 @@ def analyze(context=None, results=None):
if __name__ == '__main__':
run_algorithm(
capital_base=10000,
data_frequency='minute',
data_frequency='daily',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='bitfinex',
algo_namespace='buy_and_hodl',
base_currency='usd',
start=pd.to_datetime('2017-11-01', utc=True),
end=pd.to_datetime('2017-11-10', utc=True),
start=pd.to_datetime('2015-03-01', utc=True),
end=pd.to_datetime('2017-10-31', utc=True),
)
+3 -2
View File
@@ -3,7 +3,8 @@
https://enigmampc.github.io/catalyst/beginner-tutorial.html
Run this example, by executing the following from your terminal:
catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle
catalyst ingest-exchange -x bitfinex -f daily -i btc_usdt
catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle
If you want to run this code using another exchange, make sure that
the asset is available on that exchange. For example, if you were to run
@@ -12,7 +13,7 @@
context.asset = symbol('btc_usdt') # note 'usdt' instead of 'usd'
and specify exchange poloniex as follows:
catalyst ingest-exchange -x poloniex -f daily -i btc_usdt
catalyst run -f buy_btc_simple.py -x poloniex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle
To see which assets are available on each exchange, visit:
+153
View File
@@ -0,0 +1,153 @@
import numpy as np
import pandas as pd
from logbook import Logger
import matplotlib.pyplot as plt
from catalyst import run_algorithm
from catalyst.api import (order, record, symbol, order_target_percent,
get_open_orders)
from catalyst.exchange.stats_utils import extract_transactions
NAMESPACE = 'dual_moving_average'
log = Logger(NAMESPACE)
def initialize(context):
context.i = 0
context.asset = symbol('ltc_usd')
context.base_price = None
def handle_data(context, data):
# define the windows for the moving averages
short_window = 50
long_window = 200
# Skip as many bars as long_window to properly compute the average
context.i += 1
if context.i < long_window:
return
# Compute moving averages calling data.history() for each
# moving average with the appropriate parameters. We choose to use
# minute bars for this simulation -> freq="1m"
# Returns a pandas dataframe.
short_mavg = data.history(context.asset, 'price',
bar_count=short_window, frequency="1m").mean()
long_mavg = data.history(context.asset, 'price',
bar_count=long_window, frequency="1m").mean()
# Let's keep the price of our asset in a more handy variable
price = data.current(context.asset, 'price')
# If base_price is not set, we use the current value. This is the
# price at the first bar which we reference to calculate price_change.
if context.base_price is None:
context.base_price = price
price_change = (price - context.base_price) / context.base_price
# Save values for later inspection
record(price=price,
cash=context.portfolio.cash,
price_change=price_change,
short_mavg=short_mavg,
long_mavg=long_mavg)
# Since we are using limit orders, some orders may not execute immediately
# we wait until all orders are executed before considering more trades.
orders = get_open_orders(context.asset)
if len(orders) > 0:
return
# Exit if we cannot trade
if not data.can_trade(context.asset):
return
# We check what's our position on our portfolio and trade accordingly
pos_amount = context.portfolio.positions[context.asset].amount
# Trading logic
if short_mavg > long_mavg and pos_amount == 0:
# we buy 100% of our portfolio for this asset
order_target_percent(context.asset, 1)
elif short_mavg < long_mavg and pos_amount > 0:
# we sell all our positions for this asset
order_target_percent(context.asset, 0)
def analyze(context, perf):
# Get the base_currency that was passed as a parameter to the simulation
base_currency = context.exchanges.values()[0].base_currency.upper()
# First chart: Plot portfolio value using base_currency
ax1 = plt.subplot(411)
perf.loc[:, ['portfolio_value']].plot(ax=ax1)
ax1.legend_.remove()
ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency))
start, end = ax1.get_ylim()
ax1.yaxis.set_ticks(np.arange(start, end, (end-start)/5))
# Second chart: Plot asset price, moving averages and buys/sells
ax2 = plt.subplot(412, sharex=ax1)
perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price')
ax2.legend_.remove()
ax2.set_ylabel('{asset}\n({base})'.format(
asset = context.asset.symbol,
base = base_currency
))
start, end = ax2.get_ylim()
ax2.yaxis.set_ticks(np.arange(start, end, (end-start)/5))
transaction_df = extract_transactions(perf)
if not transaction_df.empty:
buy_df = transaction_df[transaction_df['amount'] > 0]
sell_df = transaction_df[transaction_df['amount'] < 0]
ax2.scatter(
buy_df.index.to_pydatetime(),
perf.loc[buy_df.index, 'price'],
marker='^',
s=100,
c='green',
label=''
)
ax2.scatter(
sell_df.index.to_pydatetime(),
perf.loc[sell_df.index, 'price'],
marker='v',
s=100,
c='red',
label=''
)
# Third chart: Compare percentage change between our portfolio
# and the price of the asset
ax3 = plt.subplot(413, sharex=ax1)
perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3)
ax3.legend_.remove()
ax3.set_ylabel('Percent Change')
start, end = ax3.get_ylim()
ax3.yaxis.set_ticks(np.arange(start, end, (end-start)/5))
# Fourth chart: Plot our cash
ax4 = plt.subplot(414, sharex=ax1)
perf.cash.plot(ax=ax4)
ax4.set_ylabel('Cash\n({})'.format(base_currency))
start, end = ax4.get_ylim()
ax4.yaxis.set_ticks(np.arange(0, end, end/5))
plt.show()
if __name__ == '__main__':
run_algorithm(
capital_base=1000,
data_frequency='minute',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='bitfinex',
algo_namespace=NAMESPACE,
base_currency='usd',
start=pd.to_datetime('2017-9-22', utc=True),
end=pd.to_datetime('2017-9-23', utc=True),
)
+1 -1
View File
@@ -248,7 +248,7 @@ if __name__ == '__main__':
# catalyst run -f catalyst/examples/mean_reversion_simple.py -x poloniex -s 2017-10-1 -e 2017-11-10 -c usdt -n mean-reversion --data-frequency minute --capital-base 10000
run_algorithm(
capital_base=10000,
data_frequency='minute',
data_frequency='daily',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
+24 -25
View File
@@ -85,7 +85,7 @@ Bug Fixes
- Fixed issue with sell orders in backtesting
- Fixed data frequency issues with data.history() in backtesting
- Fixed an issue with can_trade()
- Reduced the commission and slippage values to account for lower volume
- Reduced the commission and slippage values to account for lower volume
transactions
Build
@@ -97,17 +97,17 @@ Documentation
~~~~~~~~~~~~~
- Improved installation notes for Windows C++ compiler and Conda
- Addition of
- Addition of
`Jupyter Notebook guide <https://enigmampc.github.io/catalyst/jupyter.html>`_
- Addition of
- Addition of
`Live Trading page <https://enigmampc.github.io/catalyst/live-trading.html>`_
- Addition of
- Addition of
`Videos page <https://enigmampc.github.io/catalyst/videos.html>`_
- Addition of
- Addition of
`Resources page <https://enigmampc.github.io/catalyst/resources.html>`_
- Addition of `Development Guidelines
- Addition of `Development Guidelines
<https://enigmampc.github.io/catalyst/development-guidelines.html>`_
- Addition of
- Addition of
`Release Notes <https://enigmampc.github.io/catalyst/releases.html>`_
- Updated code docstrings
@@ -158,10 +158,10 @@ Bug Fixes
~~~~~~~~~
- Fixed OS-dependent path issue in data bundle
- Changed handling of empty ``auth.json``, instead of throwing an error for
- Changed handling of empty ``auth.json``, instead of throwing an error for
missing file
- Updated ``etc/python2.7-environment.yml`` to work with Catalyst version 0.3
- Updated ``catalyst/examples/buy_and_hodl.py`` and
- Updated ``catalyst/examples/buy_and_hodl.py`` and
``catalyst/examples/buy_low_sell_high.py`` to work with Catalyst version 0.3
@@ -181,18 +181,18 @@ Version 0.2.dev5
^^^^^^^^^^^^^^^^
**Release Date**: 2017-10-03
- Fixes bug in data.history function that was formatting 'volume' data as
integers, now they are returned as floats with up to 9 decimals of precision.
- Fixes bug in data.history function that was formatting 'volume' data as
integers, now they are returned as floats with up to 9 decimals of precision.
Data bundles redone.
Version 0.2.dev4
Version 0.2.dev4
^^^^^^^^^^^^^^^^
**Release Date**: 2017-09-20
- Fixes bug in the pricing resolution of 1-minute data, now set to 8 decimal
- Fixes bug in the pricing resolution of 1-minute data, now set to 8 decimal
places. Pricing resolution of daily data remains set to 9 decimal places.
- The current data bundle takes 340MB compressed for download, and 460MB
- The current data bundle takes 340MB compressed for download, and 460MB
uncompressed on disk for Catalyst to use.
Version 0.2.dev3
@@ -202,14 +202,14 @@ Version 0.2.dev3
- 1-minute resolution OHLCV data bundle for backtesting from Poloniex exchange
- Implementation of trading of fractional crypto assets (i.e. 0.01 BTC)
- Minimum trade size of a coin can be configured on a per-coin basis, defaults
to 0.00000001 in backtesting (most exchanges set the minimum trade to larger
- Minimum trade size of a coin can be configured on a per-coin basis, defaults
to 0.00000001 in backtesting (most exchanges set the minimum trade to larger
amounts, which will impact live trading)
- Increased pricing resolution from 3 to 9 decimal places
- The current data bundle takes 40MB compressed for download, and 99MB
- The current data bundle takes 40MB compressed for download, and 99MB
uncompressed on disk for Catalyst to use.
Version 0.2.dev2
Version 0.2.dev2
^^^^^^^^^^^^^^^^
**Release Date**: 2017-09-07
@@ -225,15 +225,15 @@ Version 0.2.dev1
- Comprehensive trading functionality against exchanges Bitfinex and Bittrex.
- Support for all trading pairs available on each exchange.
- Multiple algorithms can trade simultaneously against a single exchange
- Multiple algorithms can trade simultaneously against a single exchange
using the same account.
- Each algorithm has a persisted state (i.e. algorithm can be stopped and
restarted preserving the state without data loss) that tracks all open
- Each algorithm has a persisted state (i.e. algorithm can be stopped and
restarted preserving the state without data loss) that tracks all open
orders, executed transactions and portfolio positions.
- Minute by minute portfolio performance metrics.
- Daily summary performance statistics compatible with pyfolio, a Python
- Daily summary performance statistics compatible with pyfolio, a Python
library for performance and risk analysis of financial portfolios
Version 0.1.dev9
@@ -241,13 +241,13 @@ Version 0.1.dev9
**Release Date**: 2017-08-28
- Retrieval of crypto benchmark from bundle, instead of hitting Poloniex
- Retrieval of crypto benchmark from bundle, instead of hitting Poloniex
exchange directly
- Change of bundle storage provider from Dropbox to AWS
- Fix issue with 1/1000 scaling issue of prices in bundle
Version 0.1.dev8
^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^
**Release Date**: 2017-08-18
@@ -267,4 +267,3 @@ Version 0.1.dev6
**Release Date**: 2017-07-13
- Initial public release