mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-22 12:40:30 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3dca74e87 | ||
|
|
c260e188b0 | ||
|
|
230b9c17eb | ||
|
|
df14a94918 | ||
|
|
cd0157347f | ||
|
|
76a8362e3d | ||
|
|
c8cc2edd36 | ||
|
|
cb870422c3 |
@@ -19,7 +19,7 @@ from catalyst.api import symbol, record, order_target_percent, \
|
||||
# state using the files included in the folder.
|
||||
from catalyst.exchange.stats_utils import extract_transactions, trend_direction
|
||||
|
||||
algo_namespace = 'mean_reversion'
|
||||
algo_namespace = 'momentum'
|
||||
log = Logger(algo_namespace)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ def initialize(context):
|
||||
# parameters or values you're going to use.
|
||||
|
||||
# In our example, we're looking at Ether in USD Tether.
|
||||
context.eth_btc = symbol('neo_usd')
|
||||
context.eth_btc = symbol('etc_usdt')
|
||||
context.base_price = None
|
||||
context.current_day = None
|
||||
context.trigger = None
|
||||
@@ -256,18 +256,18 @@ if __name__ == '__main__':
|
||||
MODE = 'backtest'
|
||||
|
||||
if MODE == 'backtest':
|
||||
# catalyst run -f catalyst/examples/mean_reversion_simple.py -x poloniex -s 2017-7-1 -e 2017-7-31 -c usdt -n mean-reversion --data-frequency minute --capital-base 10000
|
||||
run_algorithm(
|
||||
capital_base=1,
|
||||
data_frequency='minute',
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='bitfinex',
|
||||
exchange_name='poloniex',
|
||||
algo_namespace=algo_namespace,
|
||||
base_currency='usd',
|
||||
start=pd.to_datetime('2017-10-1', utc=True),
|
||||
end=pd.to_datetime('2017-11-13', utc=True),
|
||||
base_currency='usdt',
|
||||
start=pd.to_datetime('2017-7-1', utc=True),
|
||||
# end=pd.to_datetime('2017-9-30', utc=True),
|
||||
end=pd.to_datetime('2017-10-31', utc=True),
|
||||
)
|
||||
|
||||
elif MODE == 'live':
|
||||
@@ -275,9 +275,9 @@ if __name__ == '__main__':
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='bitfinex',
|
||||
exchange_name='poloniex',
|
||||
live=True,
|
||||
algo_namespace=algo_namespace,
|
||||
base_currency='usd',
|
||||
base_currency='usdt',
|
||||
live_graph=True
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ from catalyst.api import symbol, record, order_target_percent, \
|
||||
# state using the files included in the folder.
|
||||
from catalyst.exchange.stats_utils import extract_transactions, trend_direction
|
||||
|
||||
algo_namespace = 'mean_reversion_simple'
|
||||
algo_namespace = 'momentum'
|
||||
log = Logger(algo_namespace)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ def initialize(context):
|
||||
# parameters or values you're going to use.
|
||||
|
||||
# In our example, we're looking at Ether in USD Tether.
|
||||
context.eth_btc = symbol('neo_usd')
|
||||
context.eth_btc = symbol('etc_usdt')
|
||||
context.base_price = None
|
||||
context.current_day = None
|
||||
|
||||
@@ -228,11 +228,11 @@ if __name__ == '__main__':
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='bitfinex',
|
||||
exchange_name='poloniex',
|
||||
algo_namespace=algo_namespace,
|
||||
base_currency='usd',
|
||||
start=pd.to_datetime('2017-10-1', utc=True),
|
||||
end=pd.to_datetime('2017-11-10', utc=True),
|
||||
base_currency='usdt',
|
||||
start=pd.to_datetime('2017-7-1', utc=True),
|
||||
end=pd.to_datetime('2017-7-31', utc=True),
|
||||
)
|
||||
|
||||
elif MODE == 'live':
|
||||
@@ -240,9 +240,9 @@ if __name__ == '__main__':
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='bitfinex',
|
||||
exchange_name='poloniex',
|
||||
live=True,
|
||||
algo_namespace=algo_namespace,
|
||||
base_currency='usd',
|
||||
base_currency='usdt',
|
||||
live_graph=True
|
||||
)
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
Requires Catalyst version 0.3.0 or above
|
||||
Tested on Catalyst version 0.3.3
|
||||
|
||||
These example aims to provide and easy way for users to learn how to collect data from the different exchanges.
|
||||
You simply need to specify the exchange and the market that you want to focus on.
|
||||
You will all see how to create a universe and filter it base on the exchange and the market you desire.
|
||||
|
||||
The example prints out the closing price of all the pairs for a given market-exchange every 30 minutes.
|
||||
The example also contains the ohlcv minute data for the past seven days which could be used to create indicators
|
||||
Use this as the backbone to create your own trading strategies.
|
||||
|
||||
Variables lookback date and date are used to ensure data for a coin existed on the lookback period specified.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from datetime import timedelta
|
||||
from catalyst import run_algorithm
|
||||
from catalyst.exchange.exchange_utils import get_exchange_symbols
|
||||
|
||||
from catalyst.api import (
|
||||
symbols,
|
||||
)
|
||||
|
||||
|
||||
def initialize(context):
|
||||
context.i = -1 # counts the minutes
|
||||
context.exchange = context.exchanges.values()[0].name.lower() # exchange name
|
||||
context.base_currency = context.exchanges.values()[0].base_currency.lower() # market base currency
|
||||
|
||||
|
||||
def handle_data(context, data):
|
||||
context.i += 1
|
||||
lookback_days = 7 # 7 days
|
||||
|
||||
# current date formatted into a string
|
||||
today = data.current_dt
|
||||
date, time = today.strftime('%Y-%m-%d %H:%M:%S').split(' ')
|
||||
lookback_date = today - timedelta(days=lookback_days) # subtract the amount of days specified in lookback
|
||||
lookback_date = lookback_date.strftime('%Y-%m-%d %H:%M:%S').split(' ')[0] # get only the date as a string
|
||||
|
||||
# update universe everyday
|
||||
new_day = 60 * 24 # assuming data_frequency='minute'
|
||||
if not context.i % new_day:
|
||||
context.universe = universe(context, lookback_date, date)
|
||||
|
||||
# get data every 30 minutes
|
||||
minutes = 30
|
||||
one_day_in_minutes = 1440 # 1440 assumes data_frequency='minute'
|
||||
lookback = one_day_in_minutes / minutes * lookback_days # get N lookback_days of history data
|
||||
if not context.i % minutes and context.universe:
|
||||
# we iterate for every pair in the current universe
|
||||
for coin in context.coins:
|
||||
pair = str(coin.symbol)
|
||||
|
||||
# 30 minute interval ohlcv data (the standard data required for candlestick or indicators/signals)
|
||||
# 30T means 30 minutes re-sampling of one minute data. change to your desire time interval.
|
||||
opened = fill(data.history(coin, 'open', bar_count=lookback, frequency='30T')).values
|
||||
high = fill(data.history(coin, 'high', bar_count=lookback, frequency='30T')).values
|
||||
low = fill(data.history(coin, 'low', bar_count=lookback, frequency='30T')).values
|
||||
close = fill(data.history(coin, 'price', bar_count=lookback, frequency='30T')).values
|
||||
volume = fill(data.history(coin, 'volume', bar_count=lookback, frequency='30T')).values
|
||||
|
||||
# close[-1] is the equivalent to current price
|
||||
# displays the minute price for each pair every 30 minutes
|
||||
print(today, pair, opened[-1], high[-1], low[-1], close[-1], volume[-1])
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------
|
||||
# -------------------------------------- Insert Your Strategy Here -----------------------------------------
|
||||
# ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def analyze(context=None, results=None):
|
||||
pass
|
||||
|
||||
|
||||
# Get the universe for a given exchange and a given base_currency market
|
||||
# Example: Poloniex BTC Market
|
||||
def universe(context, lookback_date, current_date):
|
||||
json_symbols = get_exchange_symbols(context.exchange) # get all the pairs for the exchange
|
||||
universe_df = pd.DataFrame.from_dict(json_symbols).transpose().astype(str) # convert into a dataframe
|
||||
universe_df['base_currency'] = universe_df.apply(lambda row: row.symbol.split('_')[1],
|
||||
axis=1)
|
||||
universe_df['market_currency'] = universe_df.apply(lambda row: row.symbol.split('_')[0],
|
||||
axis=1)
|
||||
|
||||
# Filter all the exchange pairs to only the ones for a give base currency
|
||||
universe_df = universe_df[universe_df['base_currency'] == context.base_currency]
|
||||
|
||||
# Filter all the pairs to ensure that pair existed in the current date range
|
||||
universe_df = universe_df[universe_df.start_date < lookback_date]
|
||||
universe_df = universe_df[universe_df.end_daily >= current_date]
|
||||
context.coins = symbols(*universe_df.symbol) # convert all the pairs to symbols
|
||||
|
||||
# print(universe_df.symbol.tolist())
|
||||
return universe_df.symbol.tolist()
|
||||
|
||||
|
||||
# Replace all NA, NAN or infinite values with its nearest value
|
||||
def fill(series):
|
||||
if isinstance(series, pd.Series):
|
||||
return series.replace([np.inf, -np.inf], np.nan).ffill().bfill()
|
||||
elif isinstance(series, np.ndarray):
|
||||
return pd.Series(series).replace([np.inf, -np.inf], np.nan).ffill().bfill().values
|
||||
else:
|
||||
return series
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
start_date = pd.to_datetime('2017-01-01', utc=True)
|
||||
end_date = pd.to_datetime('2017-11-13', utc=True)
|
||||
|
||||
performance = run_algorithm(start=start_date, end=end_date,
|
||||
capital_base=100.0, # amount of base_currency, not always in dollars unless usd
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='poloniex',
|
||||
data_frequency='minute',
|
||||
base_currency='btc',
|
||||
live=False,
|
||||
live_graph=False,
|
||||
algo_namespace='simple_universe')
|
||||
|
||||
"""
|
||||
Run in Terminal (inside catalyst environment):
|
||||
python simple_universe.py
|
||||
"""
|
||||
@@ -1,364 +0,0 @@
|
||||
# Run Command
|
||||
# catalyst run --start 2017-1-1 --end 2017-11-1 -o talib_simple.pickle -f talib_simple.py -x poloniex
|
||||
#
|
||||
# Description
|
||||
# Simple TALib Example showing how to use various indicators in you strategy
|
||||
# Based loosly on https://github.com/mellertson/talib-macd-example/blob/master/talib-macd-matplotlib-example.py
|
||||
|
||||
import os
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import talib as ta
|
||||
from logbook import Logger
|
||||
from matplotlib.dates import date2num
|
||||
from matplotlib.finance import candlestick_ohlc
|
||||
|
||||
from catalyst import run_algorithm
|
||||
from catalyst.api import (
|
||||
order,
|
||||
order_target_percent,
|
||||
symbol,
|
||||
)
|
||||
from catalyst.exchange.stats_utils import get_pretty_stats
|
||||
|
||||
algo_namespace = 'talib_sample'
|
||||
log = Logger(algo_namespace)
|
||||
|
||||
|
||||
def initialize(context):
|
||||
log.info('Starting TALib Simple Example')
|
||||
|
||||
context.ASSET_NAME = 'BTC_USDT'
|
||||
context.asset = symbol(context.ASSET_NAME)
|
||||
|
||||
context.ORDER_SIZE = 10
|
||||
context.SLIPPAGE_ALLOWED = 0.05
|
||||
|
||||
context.swallow_errors = True
|
||||
context.errors = []
|
||||
|
||||
# Bars to look at per iteration should be bigger than SMA_SLOW
|
||||
context.BARS = 365
|
||||
context.COUNT = 0
|
||||
|
||||
# Technical Analysis Settings
|
||||
context.SMA_FAST = 50
|
||||
context.SMA_SLOW = 100
|
||||
context.RSI_PERIOD = 14
|
||||
context.RSI_OVER_BOUGHT = 80
|
||||
context.RSI_OVER_SOLD = 20
|
||||
context.RSI_AVG_PERIOD = 15
|
||||
context.MACD_FAST = 12
|
||||
context.MACD_SLOW = 26
|
||||
context.MACD_SIGNAL = 9
|
||||
context.STOCH_K = 14
|
||||
context.STOCH_D = 3
|
||||
context.STOCH_OVER_BOUGHT = 80
|
||||
context.STOCH_OVER_SOLD = 20
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def _handle_data(context, data):
|
||||
# Get price, open, high, low, close
|
||||
prices = data.history(
|
||||
context.asset,
|
||||
bar_count=context.BARS,
|
||||
fields=['price', 'open', 'high', 'low', 'close'],
|
||||
frequency='1d')
|
||||
|
||||
# Create a analysis data frame
|
||||
analysis = pd.DataFrame(index=prices.index)
|
||||
|
||||
# SMA FAST
|
||||
analysis['sma_f'] = ta.SMA(prices.close.as_matrix(), context.SMA_FAST)
|
||||
# SMA SLOW
|
||||
analysis['sma_s'] = ta.SMA(prices.close.as_matrix(), context.SMA_SLOW)
|
||||
|
||||
# Relative Strength Index
|
||||
analysis['rsi'] = ta.RSI(prices.close.as_matrix(), context.RSI_PERIOD)
|
||||
# RSI SMA
|
||||
analysis['sma_r'] = ta.SMA(analysis.rsi.as_matrix(),
|
||||
context.RSI_AVG_PERIOD)
|
||||
|
||||
# MACD, MACD Signal, MACD Histogram
|
||||
analysis['macd'], analysis['macdSignal'], analysis['macdHist'] = ta.MACD(
|
||||
prices.close.as_matrix(), fastperiod=context.MACD_FAST,
|
||||
slowperiod=context.MACD_SLOW, signalperiod=context.MACD_SIGNAL)
|
||||
|
||||
# Stochastics %K %D
|
||||
# %K = (Current Close - Lowest Low)/(Highest High - Lowest Low) * 100
|
||||
# %D = 3-day SMA of %K
|
||||
analysis['stoch_k'], analysis['stoch_d'] = ta.STOCH(
|
||||
prices.high.as_matrix(), prices.low.as_matrix(),
|
||||
prices.close.as_matrix(), slowk_period=context.STOCH_K,
|
||||
slowd_period=context.STOCH_D)
|
||||
|
||||
# SMA FAST over SLOW Crossover
|
||||
analysis['sma_test'] = np.where(analysis.sma_f > analysis.sma_s, 1, 0)
|
||||
|
||||
# MACD over Signal Crossover
|
||||
analysis['macd_test'] = np.where((analysis.macd > analysis.macdSignal), 1,
|
||||
0)
|
||||
|
||||
# Stochastics OVER BOUGHT & Decreasing
|
||||
analysis['stoch_over_bought'] = np.where(
|
||||
(analysis.stoch_k > context.STOCH_OVER_BOUGHT) & (
|
||||
analysis.stoch_k > analysis.stoch_k.shift(1)), 1, 0)
|
||||
|
||||
# Stochastics OVER SOLD & Increasing
|
||||
analysis['stoch_over_sold'] = np.where(
|
||||
(analysis.stoch_k < context.STOCH_OVER_SOLD) & (
|
||||
analysis.stoch_k > analysis.stoch_k.shift(1)), 1, 0)
|
||||
|
||||
# RSI OVER BOUGHT & Decreasing
|
||||
analysis['rsi_over_bought'] = np.where(
|
||||
(analysis.rsi > context.RSI_OVER_BOUGHT) & (
|
||||
analysis.rsi < analysis.rsi.shift(1)), 1, 0)
|
||||
|
||||
# RSI OVER SOLD & Increasing
|
||||
analysis['rsi_over_sold'] = np.where(
|
||||
(analysis.rsi < context.RSI_OVER_SOLD) & (
|
||||
analysis.rsi > analysis.rsi.shift(1)), 1, 0)
|
||||
|
||||
# Save the prices and analysis to send to analyze
|
||||
context.prices = prices
|
||||
context.analysis = analysis
|
||||
context.price = data.current(context.asset, 'price')
|
||||
|
||||
makeOrders(context, analysis)
|
||||
|
||||
# Log the values of this bar
|
||||
logAnalysis(analysis)
|
||||
|
||||
|
||||
def handle_data(context, data):
|
||||
log.info('handling bar {}'.format(data.current_dt))
|
||||
try:
|
||||
_handle_data(context, data)
|
||||
except Exception as e:
|
||||
log.warn('aborting the bar on error {}'.format(e))
|
||||
context.errors.append(e)
|
||||
|
||||
log.info('completed bar {}, total execution errors {}'.format(
|
||||
data.current_dt,
|
||||
len(context.errors)
|
||||
))
|
||||
|
||||
if len(context.errors) > 0:
|
||||
log.info('the errors:\n{}'.format(context.errors))
|
||||
|
||||
|
||||
def analyze(context, results):
|
||||
# Save results in CSV file
|
||||
filename = os.path.splitext(os.path.basename('talib_simple'))[0]
|
||||
results.to_csv(filename + '.csv')
|
||||
|
||||
log.info('the daily stats:\n{}'.format(get_pretty_stats(results)))
|
||||
chart(context, context.prices, context.analysis, results)
|
||||
pass
|
||||
|
||||
|
||||
def makeOrders(context, analysis):
|
||||
if context.asset in context.portfolio.positions:
|
||||
|
||||
# Current position
|
||||
position = context.portfolio.positions[context.asset]
|
||||
|
||||
if (position == 0):
|
||||
log.info('Position Zero')
|
||||
return
|
||||
|
||||
# Cost Basis
|
||||
cost_basis = position.cost_basis
|
||||
|
||||
log.info(
|
||||
'Holdings: {amount} @ {cost_basis}'.format(
|
||||
amount=position.amount,
|
||||
cost_basis=cost_basis
|
||||
)
|
||||
)
|
||||
|
||||
# Sell when holding and got sell singnal
|
||||
if isSell(context, analysis):
|
||||
profit = (context.price * position.amount) - (
|
||||
cost_basis * position.amount)
|
||||
order_target_percent(
|
||||
asset=context.asset,
|
||||
target=0,
|
||||
limit_price=context.price * (1 - context.SLIPPAGE_ALLOWED),
|
||||
)
|
||||
log.info(
|
||||
'Sold {amount} @ {price} Profit: {profit}'.format(
|
||||
amount=position.amount,
|
||||
price=context.price,
|
||||
profit=profit
|
||||
)
|
||||
)
|
||||
else:
|
||||
log.info('no buy or sell opportunity found')
|
||||
else:
|
||||
# Buy when not holding and got buy signal
|
||||
if isBuy(context, analysis):
|
||||
order(
|
||||
asset=context.asset,
|
||||
amount=context.ORDER_SIZE,
|
||||
limit_price=context.price * (1 + context.SLIPPAGE_ALLOWED)
|
||||
)
|
||||
log.info(
|
||||
'Bought {amount} @ {price}'.format(
|
||||
amount=context.ORDER_SIZE,
|
||||
price=context.price
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def isBuy(context, analysis):
|
||||
# Bullish SMA Crossover
|
||||
if (getLast(analysis, 'sma_test') == 1):
|
||||
# Bullish MACD
|
||||
if (getLast(analysis, 'macd_test') == 1):
|
||||
return True
|
||||
|
||||
# # Bullish Stochastics
|
||||
# if(getLast(analysis, 'stoch_over_sold') == 1):
|
||||
# return True
|
||||
|
||||
# # Bullish RSI
|
||||
# if(getLast(analysis, 'rsi_over_sold') == 1):
|
||||
# return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def isSell(context, analysis):
|
||||
# Bearish SMA Crossover
|
||||
if (getLast(analysis, 'sma_test') == 0):
|
||||
# Bearish MACD
|
||||
if (getLast(analysis, 'macd_test') == 0):
|
||||
return True
|
||||
|
||||
# # Bearish Stochastics
|
||||
# if(getLast(analysis, 'stoch_over_bought') == 0):
|
||||
# return True
|
||||
|
||||
# # Bearish RSI
|
||||
# if(getLast(analysis, 'rsi_over_bought') == 0):
|
||||
# return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def chart(context, prices, analysis, results):
|
||||
results.portfolio_value.plot()
|
||||
|
||||
# Data for matplotlib finance plot
|
||||
dates = date2num(prices.index.to_pydatetime())
|
||||
|
||||
# Create the Open High Low Close Tuple
|
||||
prices_ohlc = [tuple([dates[i],
|
||||
prices.open[i],
|
||||
prices.high[i],
|
||||
prices.low[i],
|
||||
prices.close[i]]) for i in range(len(dates))]
|
||||
|
||||
fig = plt.figure(figsize=(14, 18))
|
||||
|
||||
# Draw the candle sticks
|
||||
ax1 = fig.add_subplot(411)
|
||||
ax1.set_ylabel(context.ASSET_NAME, size=20)
|
||||
candlestick_ohlc(ax1, prices_ohlc, width=0.4, colorup='g', colordown='r')
|
||||
|
||||
# Draw Moving Averages
|
||||
analysis.sma_f.plot(ax=ax1, c='r')
|
||||
analysis.sma_s.plot(ax=ax1, c='g')
|
||||
|
||||
# RSI
|
||||
ax2 = fig.add_subplot(412)
|
||||
ax2.set_ylabel('RSI', size=12)
|
||||
analysis.rsi.plot(ax=ax2, c='g',
|
||||
label='Period: ' + str(context.RSI_PERIOD))
|
||||
analysis.sma_r.plot(ax=ax2, c='r',
|
||||
label='MA: ' + str(context.RSI_AVG_PERIOD))
|
||||
ax2.axhline(y=30, c='b')
|
||||
ax2.axhline(y=50, c='black')
|
||||
ax2.axhline(y=70, c='b')
|
||||
ax2.set_ylim([0, 100])
|
||||
handles, labels = ax2.get_legend_handles_labels()
|
||||
ax2.legend(handles, labels)
|
||||
|
||||
# Draw MACD computed with Talib
|
||||
ax3 = fig.add_subplot(413)
|
||||
ax3.set_ylabel('MACD: ' + str(context.MACD_FAST) + ', ' + str(
|
||||
context.MACD_SLOW) + ', ' + str(context.MACD_SIGNAL), size=12)
|
||||
analysis.macd.plot(ax=ax3, color='b', label='Macd')
|
||||
analysis.macdSignal.plot(ax=ax3, color='g', label='Signal')
|
||||
analysis.macdHist.plot(ax=ax3, color='r', label='Hist')
|
||||
ax3.axhline(0, lw=2, color='0')
|
||||
handles, labels = ax3.get_legend_handles_labels()
|
||||
ax3.legend(handles, labels)
|
||||
|
||||
# Stochastic plot
|
||||
ax4 = fig.add_subplot(414)
|
||||
ax4.set_ylabel('Stoch (k,d)', size=12)
|
||||
analysis.stoch_k.plot(ax=ax4, label='stoch_k:' + str(context.STOCH_K),
|
||||
color='r')
|
||||
analysis.stoch_d.plot(ax=ax4, label='stoch_d:' + str(context.STOCH_D),
|
||||
color='g')
|
||||
handles, labels = ax4.get_legend_handles_labels()
|
||||
ax4.legend(handles, labels)
|
||||
ax4.axhline(y=20, c='b')
|
||||
ax4.axhline(y=50, c='black')
|
||||
ax4.axhline(y=80, c='b')
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
def logAnalysis(analysis):
|
||||
# Log only the last value in the array
|
||||
log.info('- sma_f: {:.2f}'.format(getLast(analysis, 'sma_f')))
|
||||
log.info('- sma_s: {:.2f}'.format(getLast(analysis, 'sma_s')))
|
||||
|
||||
log.info('- rsi: {:.2f}'.format(getLast(analysis, 'rsi')))
|
||||
log.info('- sma_r: {:.2f}'.format(getLast(analysis, 'sma_r')))
|
||||
|
||||
log.info('- macd: {:.2f}'.format(getLast(analysis, 'macd')))
|
||||
log.info(
|
||||
'- macdSignal: {:.2f}'.format(getLast(analysis, 'macdSignal')))
|
||||
log.info('- macdHist: {:.2f}'.format(getLast(analysis, 'macdHist')))
|
||||
|
||||
log.info('- stoch_k: {:.2f}'.format(getLast(analysis, 'stoch_k')))
|
||||
log.info('- stoch_d: {:.2f}'.format(getLast(analysis, 'stoch_d')))
|
||||
|
||||
log.info('- sma_test: {}'.format(getLast(analysis, 'sma_test')))
|
||||
log.info('- macd_test: {}'.format(getLast(analysis, 'macd_test')))
|
||||
|
||||
log.info('- stoch_over_bought: {}'.format(
|
||||
getLast(analysis, 'stoch_over_bought')))
|
||||
log.info(
|
||||
'- stoch_over_sold: {}'.format(getLast(analysis, 'stoch_over_sold')))
|
||||
|
||||
log.info('- rsi_over_bought: {}'.format(
|
||||
getLast(analysis, 'rsi_over_bought')))
|
||||
log.info(
|
||||
'- rsi_over_sold: {}'.format(getLast(analysis, 'rsi_over_sold')))
|
||||
|
||||
|
||||
def getLast(arr, name):
|
||||
return arr[name][arr[name].index[-1]]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_algorithm(
|
||||
capital_base=10000,
|
||||
data_frequency='daily',
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=analyze,
|
||||
exchange_name='poloniex',
|
||||
base_currency='usdt',
|
||||
start=pd.to_datetime('2016-11-1', utc=True),
|
||||
end=pd.to_datetime('2017-11-10', utc=True),
|
||||
)
|
||||
@@ -226,10 +226,9 @@ class Poloniex(Exchange):
|
||||
ohlc_map = dict()
|
||||
|
||||
for asset in asset_list:
|
||||
delta = end_dt - pd.to_datetime('1970-1-1', utc=True)
|
||||
end = int(delta.total_seconds())
|
||||
|
||||
# TODO: what's wrong with this?
|
||||
# end = int(time.mktime(end_dt.timetuple()))
|
||||
end = int(time.time())
|
||||
if bar_count is None:
|
||||
start = end - 2 * frequency
|
||||
else:
|
||||
|
||||
+9
-53
@@ -136,17 +136,14 @@ about matplotlib backends, please refer to the
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
In Windows, you will first need to install the `Microsoft Visual C++ Compiler
|
||||
for Python 2.7
|
||||
In Windows, you will need the `Microsoft Visual C++ Compiler for Python 2.7
|
||||
<https://www.microsoft.com/en-us/download/details.aspx?id=44266>`_. This
|
||||
package contains the compiler and the set of system headers necessary for
|
||||
producing binary wheels for Python 2.7 packages. If it's not already in your
|
||||
system, download it and install it before proceeding to the next step.
|
||||
|
||||
Once you have the above compiler installed, the easiest and best supported way
|
||||
to install Catalyst in Windows is to use :ref:`Conda <conda>`. If you didn't
|
||||
any problems installing the compiler, jump to the :ref:`Conda <conda>` section,
|
||||
otherwise keep on reading to troubleshoot the C++ compiler installtion.
|
||||
For windows, the easiest and best supported way to install Catalyst is to use
|
||||
:ref:`Conda <conda>`.
|
||||
|
||||
Some problems we have encountered installing the **Visual C++ Compiler**
|
||||
mentioned above are as follows:
|
||||
@@ -161,8 +158,6 @@ mentioned above are as follows:
|
||||
``Registry Editor``
|
||||
- Navigate to the following folder:
|
||||
``HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer``
|
||||
- If the last folder does not exist, create it by right-clicking on the
|
||||
parent folder and choosing -> ``New`` -> ``Key`` and typing ``Installer``
|
||||
- If there is an entry for ``DisableMSI``, set the Value data to 0.
|
||||
- If there is no such entry, click on the ``Edit`` menu -> ``New`` ->
|
||||
``DWORD (32-bit) Value`` and enter ``DisableMSI`` as the Name (and by
|
||||
@@ -307,9 +302,9 @@ understands the complex binary dependencies of packages like ``numpy`` and
|
||||
dependencies without requiring the use of a second tool to acquire Catalyst's
|
||||
non-Python dependencies.
|
||||
|
||||
For Windows, you will first need to install the *Microsoft Visual C++
|
||||
Compiler for Python 2.7*. Follow the instructions on the :ref:`Windows`
|
||||
section and come back here.
|
||||
For Windows, you will need the *Microsoft Visual C++ Compiler for Python
|
||||
2.7*. Follow the instructions on the :ref:`Windows` section and come back
|
||||
here.
|
||||
|
||||
For instructions on how to install ``conda``, see the `Conda Installation
|
||||
Documentation <http://conda.pydata.org/docs/download.html>`_. Alternatively,
|
||||
@@ -324,23 +319,10 @@ main packages needed. To install MiniConda, you can follow these steps:
|
||||
3. Ensure the correct installation by running ``conda list`` in a Terminal
|
||||
window, which should print the list of packages installed with Conda.
|
||||
|
||||
For Windows, if you accepted the default installation options, you didn't
|
||||
check an option to add Conda to the PATH, so trying to run ``conda`` from
|
||||
a regular ``Command Prompt`` will result in the following error: ``'conda'
|
||||
is no recognized as an internal or external command, operatble program or
|
||||
batch file``. That's to be expected. You will nee to launch an ``Anaconda
|
||||
Prompt`` that was added at installation time to your list of programs
|
||||
available from the Start menu.
|
||||
|
||||
Once either Conda or MiniConda has been set up you can install Catalyst:
|
||||
|
||||
1. Download the file `python2.7-environment.yml
|
||||
<https://github.com/enigmampc/catalyst/blob/master/etc/python2.7-environment.yml>`_.
|
||||
|
||||
To download, simply click on the 'Raw' button and save the file locally to
|
||||
a folder you can remember. Make sure that the file gets saved with the ``.yml``
|
||||
extension, and nothing like a ``.txt`` file or anything else.
|
||||
|
||||
2. Open a Terminal window and enter [``cd/dir``] into the directory where you
|
||||
saved the above ``python2.7-environment.yml`` file.
|
||||
3. Install using this file. This step can take about 5-10 minutes to install.
|
||||
@@ -364,14 +346,6 @@ Once either Conda or MiniConda has been set up you can install Catalyst:
|
||||
|
||||
activate catalyst
|
||||
|
||||
5. Verify that Catalyst is install correctly:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
catalyst --version
|
||||
|
||||
which should display the current version.
|
||||
|
||||
Congratulations! You now have Catalyst installed.
|
||||
|
||||
Troubleshooting ``conda`` Install
|
||||
@@ -381,21 +355,13 @@ If the command ``conda env create -f python2.7-environment.yml`` in step 3
|
||||
above failed for any reason, you can try setting up the environment manually
|
||||
with the following steps:
|
||||
|
||||
1. If the above installation failed, and you have a partially set up catalyst
|
||||
environment, remove it first. If you are starting from scratch, proceed to
|
||||
step #2:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
conda env remove --name catalyst
|
||||
|
||||
2. Create the environment:
|
||||
1. Create the environment:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
conda create --name catalyst python=2.7 scipy zlib
|
||||
|
||||
3. Activate the environment:
|
||||
2. Activate the environment:
|
||||
|
||||
**Linux or OSX:**
|
||||
|
||||
@@ -409,22 +375,12 @@ with the following steps:
|
||||
|
||||
activate catalyst
|
||||
|
||||
4. Install the Catalyst inside the environment:
|
||||
3. Install the Catalyst inside the environment:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install enigma-catalyst matplotlib
|
||||
|
||||
5. Verify that Catalyst is installed correctly:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
catalyst --version
|
||||
|
||||
which should display the current version.
|
||||
|
||||
Congratulations! You now have Catalyst properly installed.
|
||||
|
||||
Getting Help
|
||||
------------
|
||||
|
||||
|
||||
@@ -113,3 +113,40 @@ class TestExchangeDataPortal:
|
||||
)
|
||||
|
||||
log.info('found history window: {}'.format(data))
|
||||
|
||||
def test_validate_resample(self):
|
||||
symbol = ['eth_btc']
|
||||
exchange_name = 'poloniex'
|
||||
exchange = get_exchange(exchange_name, base_currency=symbol)
|
||||
|
||||
assets = exchange.get_assets(symbols=symbol)
|
||||
|
||||
date = rnd_history_date_days(
|
||||
max_days=10,
|
||||
last_dt=pd.to_datetime('2017-11-1', utc=True)
|
||||
)
|
||||
bar_count = rnd_bar_count(max_bars=10)
|
||||
sample_minutes = 15
|
||||
sample_data = self.data_portal_backtest.get_history_window(
|
||||
assets=assets,
|
||||
end_dt=date,
|
||||
bar_count=bar_count,
|
||||
frequency='{}T'.format(sample_minutes),
|
||||
field='close',
|
||||
data_frequency='daily'
|
||||
)
|
||||
minute_data = self.data_portal_backtest.get_history_window(
|
||||
assets=assets,
|
||||
end_dt=date,
|
||||
bar_count=bar_count * sample_minutes,
|
||||
frequency='1T',
|
||||
field='close',
|
||||
data_frequency='daily'
|
||||
)
|
||||
resampled_minute_data = minute_data.resample(
|
||||
'{}T'.format(sample_minutes))
|
||||
|
||||
print(sample_data.tail(10))
|
||||
print(resampled_minute_data.tail(10))
|
||||
print(minute_data.tail(10))
|
||||
pass
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from catalyst.exchange.bittrex.bittrex import Bittrex
|
||||
from catalyst.exchange.poloniex.poloniex import Poloniex
|
||||
from catalyst.finance.order import Order
|
||||
from base import BaseExchangeTestCase
|
||||
from logbook import Logger
|
||||
from catalyst.exchange.exchange_utils import get_exchange_auth
|
||||
import pandas as pd
|
||||
from test_utils import output_df
|
||||
|
||||
log = Logger('test_poloniex')
|
||||
|
||||
@@ -51,18 +52,19 @@ class TestPoloniex(BaseExchangeTestCase):
|
||||
|
||||
def test_get_candles(self):
|
||||
log.info('retrieving candles')
|
||||
ohlcv_neo = self.exchange.get_candles(
|
||||
freq='5T',
|
||||
assets=self.exchange.get_asset('eth_btc')
|
||||
)
|
||||
ohlcv_neo_ubq = self.exchange.get_candles(
|
||||
freq='5T',
|
||||
assets=[
|
||||
self.exchange.get_asset('neos_btc'),
|
||||
self.exchange.get_asset('via_btc')
|
||||
],
|
||||
bar_count=14
|
||||
assets = self.exchange.get_asset('eth_btc')
|
||||
ohlcv = self.exchange.get_candles(
|
||||
end_dt=pd.to_datetime('2017-11-01', utc=True),
|
||||
freq='30T',
|
||||
assets=assets,
|
||||
bar_count=200
|
||||
)
|
||||
df = pd.DataFrame(ohlcv)
|
||||
df.set_index('last_traded', drop=True, inplace=True)
|
||||
log.info(df.tail(25))
|
||||
|
||||
path = output_df(df, assets, 'candles')
|
||||
log.info('saved candles: {}'.format(path))
|
||||
pass
|
||||
|
||||
def test_tickers(self):
|
||||
|
||||
@@ -4,11 +4,20 @@ from random import randint
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def rnd_history_date_days(max_days=30):
|
||||
now = pd.Timestamp.utcnow()
|
||||
def rnd_history_date_days(max_days=30, last_dt=None):
|
||||
if last_dt is None:
|
||||
last_dt = pd.Timestamp.utcnow()
|
||||
|
||||
days = randint(0, max_days)
|
||||
|
||||
return now - timedelta(days=days)
|
||||
return last_dt - timedelta(days=days)
|
||||
|
||||
|
||||
def rnd_history_date_minutes(max_minutes=1440):
|
||||
now = pd.Timestamp.utcnow()
|
||||
days = randint(0, max_minutes)
|
||||
|
||||
return now - timedelta(minutes=days)
|
||||
|
||||
|
||||
def rnd_bar_count(max_bars=21):
|
||||
|
||||
Reference in New Issue
Block a user