BLD: misc housekeeping

This commit is contained in:
fredfortier
2017-11-16 16:55:40 -05:00
parent e087e48088
commit 3fa88a3e56
7 changed files with 129 additions and 66 deletions
+21 -3
View File
@@ -14,7 +14,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pandas as pd
from catalyst import run_algorithm
from catalyst.api import (
order_target_value,
symbol,
@@ -23,6 +25,7 @@ from catalyst.api import (
get_open_orders,
)
def initialize(context):
context.ASSET_NAME = 'BTC_USDT'
context.TARGET_HODL_RATIO = 0.8
@@ -38,6 +41,7 @@ def initialize(context):
context.i = 0
def handle_data(context, data):
context.i += 1
@@ -64,8 +68,8 @@ def handle_data(context, data):
order_target_value(
context.asset,
target_hodl_value,
limit_price=price*1.1,
stop_price=price*0.9,
limit_price=price * 1.1,
stop_price=price * 0.9,
)
record(
@@ -76,6 +80,7 @@ def handle_data(context, data):
leverage=context.account.leverage,
)
def analyze(context=None, results=None):
import matplotlib.pyplot as plt
@@ -134,4 +139,17 @@ def analyze(context=None, results=None):
# Show the plot.
plt.gcf().set_size_inches(18, 8)
plt.show()
plt.show()
run_algorithm(
capital_base=10000,
data_frequency='minute',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='poloniex',
base_currency='usd',
start=pd.to_datetime('2017-10-1', utc=True),
end=pd.to_datetime('2017-11-10', utc=True),
)
+17 -19
View File
@@ -1,14 +1,12 @@
# For this example, we're going to write a simple momentum script. When the
# stock goes up quickly, we're going to buy; when it goes down quickly, we're
# going to sell. Hopefully we'll ride the waves.
from datetime import timedelta
import pandas as pd
import talib
# To run an algorithm in Catalyst, you need two functions: initialize and
# handle_data.
from logbook import Logger
from talib.common import MA_Type
from catalyst import run_algorithm
from catalyst.api import symbol, record, order_target_percent, \
@@ -17,10 +15,10 @@ from catalyst.api import symbol, record, order_target_percent, \
# In this example, Catalyst will create the `.catalyst/data/live_algos`
# directory. If we stop and start the algorithm, Catalyst will resume its
# state using the files included in the folder.
from catalyst.exchange.stats_utils import extract_transactions, trend_direction
from catalyst.exchange.stats_utils import extract_transactions
algo_namespace = 'mean_reversion_simple'
log = Logger(algo_namespace)
NAMESPACE = 'mean_reversion_simple'
log = Logger(NAMESPACE)
def initialize(context):
@@ -30,7 +28,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.neo_usd = symbol('neo_usd')
context.base_price = None
context.current_day = None
@@ -50,14 +48,14 @@ def handle_data(context, data):
context.current_day = today
# We're computing the volume-weighted-average-price of the security
# defined above, in the context.eth_btc variable. For this example, we're
# defined above, in the context.neo_usd variable. For this example, we're
# using three bars on the 15 min bars.
# The frequency attribute determine the bar size. We use this convention
# for the frequency alias:
# http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
prices = data.history(
context.eth_btc,
context.neo_usd,
fields='close',
bar_count=50,
frequency='15T'
@@ -72,7 +70,7 @@ def handle_data(context, data):
# We need a variable for the current price of the security to compare to
# the average. Since we are requesting two fields, data.current()
# returns a DataFrame with
current = data.current(context.eth_btc, fields=['close', 'volume'])
current = data.current(context.neo_usd, fields=['close', 'volume'])
price = current['close']
# If base_price is not set, we use the current value. This is the
@@ -101,19 +99,19 @@ def handle_data(context, data):
# 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.eth_btc)
orders = get_open_orders(context.neo_usd)
if len(orders) > 0:
return
# Exit if we cannot trade
if not data.can_trade(context.eth_btc):
if not data.can_trade(context.neo_usd):
return
# Another powerful built-in feature of the Catalyst backtester is the
# portfolio object. The portfolio object tracks your positions, cash,
# cost basis of specific holdings, and more. In this line, we calculate
# how long or short our position is at this minute.
pos_amount = context.portfolio.positions[context.eth_btc].amount
pos_amount = context.portfolio.positions[context.neo_usd].amount
if rsi[-1] <= 30 and pos_amount == 0:
log.info(
@@ -121,7 +119,7 @@ def handle_data(context, data):
data.current_dt, price, rsi[-1]
)
)
order_target_percent(context.eth_btc, 1)
order_target_percent(context.neo_usd, 1)
context.traded_today = True
elif rsi[-1] >= 80 and pos_amount > 0:
@@ -130,7 +128,7 @@ def handle_data(context, data):
data.current_dt, price, rsi[-1]
)
)
order_target_percent(context.eth_btc, 0)
order_target_percent(context.neo_usd, 0)
context.traded_today = True
@@ -150,7 +148,7 @@ def analyze(context=None, perf=None):
perf.loc[:, 'price'].plot(ax=ax2, label='Price')
ax2.set_ylabel('{asset} ({base})'.format(
asset=context.eth_btc.symbol, base=base_currency
asset=context.neo_usd.symbol, base=base_currency
))
transaction_df = extract_transactions(perf)
@@ -218,10 +216,10 @@ def analyze(context=None, perf=None):
if __name__ == '__main__':
# The execution mode: backtest or live
MODE = 'backtest'
MODE = 'live'
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
# 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',
@@ -229,7 +227,7 @@ if __name__ == '__main__':
handle_data=handle_data,
analyze=analyze,
exchange_name='bitfinex',
algo_namespace=algo_namespace,
algo_namespace=NAMESPACE,
base_currency='usd',
start=pd.to_datetime('2017-10-1', utc=True),
end=pd.to_datetime('2017-11-10', utc=True),
@@ -242,7 +240,7 @@ if __name__ == '__main__':
analyze=analyze,
exchange_name='bitfinex',
live=True,
algo_namespace=algo_namespace,
algo_namespace=NAMESPACE,
base_currency='usd',
live_graph=True
)
+17 -17
View File
@@ -250,27 +250,27 @@ def analyze(context=None, results=None):
pass
run_algorithm(
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='bittrex',
live=True,
algo_namespace=algo_namespace,
base_currency='btc',
live_graph=False
)
# Backtest
# run_algorithm(
# capital_base=0.5,
# data_frequency='minute',
# initialize=initialize,
# handle_data=handle_data,
# analyze=analyze,
# exchange_name='poloniex',
# exchange_name='bittrex',
# live=True,
# algo_namespace=algo_namespace,
# base_currency='btc',
# start=pd.to_datetime('2017-9-1', utc=True),
# end=pd.to_datetime('2017-10-1', utc=True),
# live_graph=False
# )
# Backtest
run_algorithm(
capital_base=0.5,
data_frequency='minute',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='poloniex',
algo_namespace=algo_namespace,
base_currency='btc',
start=pd.to_datetime('2017-9-1', utc=True),
end=pd.to_datetime('2017-10-1', utc=True),
)
+17 -6
View File
@@ -30,14 +30,25 @@ def crossover(source, target):
bool
"""
if source[-1] is np.nan or source[-2] is np.nan \
or target[-1] is np.nan or target[-2] is np.nan:
return False
if isinstance(target, numbers.Number):
if source[-1] is np.nan or source[-2] is np.nan \
or target is np.nan:
return False
if source[-1] >= target > source[-2]:
return True
else:
return False
if source[-1] > target[-1] and source[-2] < target[-2]:
return True
else:
return False
if source[-1] is np.nan or source[-2] is np.nan \
or target[-1] is np.nan or target[-2] is np.nan:
return False
if source[-1] > target[-1] and source[-2] < target[-2]:
return True
else:
return False
def crossunder(source, target):
+13 -14
View File
@@ -1,6 +1,6 @@
"""
Requires Catalyst version 0.3.0 or above
Tested on Catalyst version 0.3.2
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.
@@ -27,7 +27,7 @@ from catalyst.api import (
def initialize(context):
context.i = -1 # counts the minutes
context.exchange = 'poloniex' # must match the exchange specified in run_algorithm
context.base_currency = 'eth' # must match the base currency specified in run_algorithm
context.base_currency = 'btc' # must match the base currency specified in run_algorithm
def handle_data(context, data):
@@ -56,21 +56,21 @@ def handle_data(context, data):
# 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.
open = fill(data.history(coin, 'open', bar_count=lookback,
frequency='1m')).resample('30T').first()
opened = fill(data.history(coin, 'open', bar_count=lookback,
frequency='30T')).values
high = fill(data.history(coin, 'high', bar_count=lookback,
frequency='1m')).resample('30T').max()
frequency='30T')).values
low = fill(data.history(coin, 'low', bar_count=lookback,
frequency='1m')).resample('30T').min()
frequency='30T')).values
close = fill(data.history(coin, 'price', bar_count=lookback,
frequency='1m')).resample('30T').last()
frequency='30T')).values
volume = fill(data.history(coin, 'volume', bar_count=lookback,
frequency='1m')).resample('30T').sum()
frequency='30T')).values
# close[-1] is the equivalent to current price
# displays the minute price for each pair every 30 minutes
print(
today, pair, open[-1], high[-1], low[-1], close[-1], volume[-1])
today, pair, opened[-1], high[-1], low[-1], close[-1], volume[-1])
# ----------------------------------------------------------------------------------------------------------
# -------------------------------------- Insert Your Strategy Here -----------------------------------------
@@ -82,7 +82,7 @@ def analyze(context=None, results=None):
# Get the universe for a given exchange and a given base_currency market
# Example: Poloniex BTC 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
@@ -103,7 +103,6 @@ def universe(context, lookback_date, current_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.head(), len(universe_df))
return universe_df.symbol.tolist()
@@ -119,8 +118,8 @@ def fill(series):
if __name__ == '__main__':
start_date = pd.to_datetime('2017-01-01', utc=True)
end_date = pd.to_datetime('2017-10-15', utc=True)
start_date = pd.to_datetime('2017-01-08', utc=True)
end_date = pd.to_datetime('2017-11-13', utc=True)
performance = run_algorithm(start=start_date, end=end_date,
capital_base=10000.0,
@@ -129,7 +128,7 @@ if __name__ == '__main__':
analyze=analyze,
exchange_name='poloniex',
data_frequency='minute',
base_currency='eth',
base_currency='btc',
live=False,
live_graph=False,
algo_namespace='simple_universe')
+42 -5
View File
@@ -1,4 +1,5 @@
import os
import re
import sys
import warnings
from datetime import timedelta
@@ -8,6 +9,8 @@ from time import sleep
import click
import pandas as pd
from catalyst.data.bundles import load
from catalyst.data.data_portal import DataPortal
from catalyst.exchange.bittrex.bittrex import Bittrex
from catalyst.exchange.bitfinex.bitfinex import Bitfinex
from catalyst.exchange.poloniex.poloniex import Poloniex
@@ -167,10 +170,12 @@ def _run(handle_data,
# This corresponds to the json file containing api token info
exchange_auth = get_exchange_auth(exchange_name)
if live and (exchange_auth['key'] == '' or exchange_auth['secret'] == ''):
if live and (
exchange_auth['key'] == '' or exchange_auth['secret'] == ''):
raise ExchangeAuthEmpty(
exchange=exchange_name.title(),
filename=os.path.join(get_exchange_folder(exchange_name, environ), 'auth.json') )
exchange=exchange_name.title(),
filename=os.path.join(
get_exchange_folder(exchange_name, environ), 'auth.json'))
if exchange_name == 'bitfinex':
exchanges[exchange_name] = Bitfinex(
@@ -287,7 +292,7 @@ def _run(handle_data,
algo_namespace=algo_namespace,
live_graph=live_graph
)
else:
elif exchanges:
# Removed the existing Poloniex fork to keep things simple
# We can add back the complexity if required.
@@ -317,6 +322,36 @@ def _run(handle_data,
exchanges=exchanges
)
elif bundle is not None:
bundle_data = load(
bundle,
environ,
bundle_timestamp,
)
prefix, connstr = re.split(
r'sqlite:///',
str(bundle_data.asset_finder.engine.url),
maxsplit=1,
)
if prefix:
raise ValueError(
"invalid url %r, must begin with 'sqlite:///'" %
str(bundle_data.asset_finder.engine.url),
)
env = TradingEnvironment(asset_db_path=connstr, environ=environ)
first_trading_day = \
bundle_data.equity_minute_bar_reader.first_trading_day
data = DataPortal(
env.asset_finder, open_calendar,
first_trading_day=first_trading_day,
equity_minute_reader=bundle_data.equity_minute_bar_reader,
equity_daily_reader=bundle_data.equity_daily_bar_reader,
adjustment_reader=bundle_data.adjustment_reader,
)
perf = algorithm_class(
namespace=namespace,
env=env,
@@ -486,7 +521,9 @@ def run_algorithm(initialize,
--------
catalyst.data.bundles.bundles : The available data bundles.
"""
load_extensions(default_extension, extensions, strict_extensions, environ)
load_extensions(
default_extension, extensions, strict_extensions, environ
)
# I'm not sure that we need this since the modified DataPortal
# does not require extensions to be explicitly loaded.
+2 -2
View File
@@ -460,8 +460,8 @@ class TestExchangeBundle:
def bundle_to_csv(self):
exchange_name = 'poloniex'
data_frequency = 'minute'
period = '2017-09'
symbol = 'eth_btc'
period = '2017-02'
symbol = 'lsk_eth'
exchange = get_exchange(exchange_name)
asset = exchange.get_asset(symbol)