mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-01 11:08:00 +08:00
Python3 adjustments
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import pandas as pd
|
||||
import talib
|
||||
|
||||
import pandas as pd
|
||||
from catalyst import run_algorithm
|
||||
from catalyst.api import symbol
|
||||
|
||||
|
||||
def initialize(context):
|
||||
print('initializing')
|
||||
context.asset = symbol('xrp_btc')
|
||||
context.asset = symbol('btc_usd')
|
||||
|
||||
|
||||
def handle_data(context, data):
|
||||
@@ -27,25 +27,25 @@ def handle_data(context, data):
|
||||
pass
|
||||
|
||||
|
||||
# run_algorithm(
|
||||
# capital_base=250,
|
||||
# start=pd.to_datetime('2015-08-01', utc=True),
|
||||
# end=pd.to_datetime('2017-9-30', utc=True),
|
||||
# data_frequency='daily',
|
||||
# initialize=initialize,
|
||||
# handle_data=handle_data,
|
||||
# analyze=None,
|
||||
# exchange_name='poloniex',
|
||||
# algo_namespace='simple_loop',
|
||||
# base_currency='eth'
|
||||
# )
|
||||
run_algorithm(
|
||||
capital_base=250,
|
||||
start=pd.to_datetime('2017-08-01', utc=True),
|
||||
end=pd.to_datetime('2017-9-30', utc=True),
|
||||
data_frequency='daily',
|
||||
initialize=initialize,
|
||||
handle_data=handle_data,
|
||||
analyze=None,
|
||||
exchange_name='bitfinex',
|
||||
live=True,
|
||||
algo_namespace='simple_loop',
|
||||
base_currency='eth',
|
||||
live_graph=False
|
||||
base_currency='btc'
|
||||
)
|
||||
# run_algorithm(
|
||||
# initialize=initialize,
|
||||
# handle_data=handle_data,
|
||||
# analyze=None,
|
||||
# exchange_name='bitfinex',
|
||||
# live=True,
|
||||
# algo_namespace='simple_loop',
|
||||
# base_currency='eth',
|
||||
# live_graph=False
|
||||
# )
|
||||
|
||||
@@ -24,7 +24,7 @@ URL2 = 'https://bittrex.com/Api/v2.0'
|
||||
|
||||
class Bittrex(Exchange):
|
||||
def __init__(self, key, secret, base_currency, portfolio=None):
|
||||
self.api = Bittrex_api(key=key, secret=secret.encode('UTF-8'))
|
||||
self.api = Bittrex_api(key=key, secret=secret)
|
||||
self.name = 'bittrex'
|
||||
self.color = 'blue'
|
||||
self.base_currency = base_currency
|
||||
@@ -65,10 +65,10 @@ class Bittrex(Exchange):
|
||||
return exchange_symbol.lower()
|
||||
|
||||
def get_balances(self):
|
||||
balances = self.api.getbalances()
|
||||
try:
|
||||
log.debug('retrieving wallet balances')
|
||||
self.ask_request()
|
||||
balances = self.api.getbalances()
|
||||
|
||||
except Exception as e:
|
||||
raise ExchangeRequestError(error=e)
|
||||
@@ -208,7 +208,7 @@ class Bittrex(Exchange):
|
||||
)
|
||||
|
||||
def get_candles(self, data_frequency, assets, bar_count=None,
|
||||
start_date=None):
|
||||
start_dt=None, end_dt=None):
|
||||
"""
|
||||
Supported Intervals
|
||||
-------------------
|
||||
|
||||
@@ -39,7 +39,10 @@ class Bittrex_api(object):
|
||||
if method not in self.public:
|
||||
url += '&apikey=' + self.key
|
||||
url += '&nonce=' + str(int(time.time()))
|
||||
signature = hmac.new(self.secret, url, hashlib.sha512).hexdigest()
|
||||
|
||||
signature = hmac.new(self.secret.encode('utf-8'),
|
||||
url.encode('utf-8'),
|
||||
hashlib.sha512).hexdigest()
|
||||
headers = {'apisign': signature}
|
||||
else:
|
||||
headers = {}
|
||||
|
||||
@@ -134,7 +134,7 @@ def get_adj_dates(start, end, assets, data_frequency):
|
||||
if end is None or start >= end:
|
||||
raise NoDataAvailableOnExchange(
|
||||
exchange=asset.exchange.title(),
|
||||
symbol=[asset.symbol.encode('utf-8')],
|
||||
symbol=[asset.symbol],
|
||||
data_frequency=data_frequency,
|
||||
)
|
||||
|
||||
@@ -243,12 +243,12 @@ def find_most_recent_time(bundle_name):
|
||||
for folder in bundle_folders:
|
||||
date = from_bundle_ingest_dirname(folder)
|
||||
if not most_recent_bundle or date > \
|
||||
most_recent_bundle[most_recent_bundle.keys()[0]]:
|
||||
most_recent_bundle[list(most_recent_bundle.keys())[0]]:
|
||||
most_recent_bundle = dict()
|
||||
most_recent_bundle[folder] = date
|
||||
|
||||
if most_recent_bundle:
|
||||
return most_recent_bundle.keys()[0]
|
||||
return list(most_recent_bundle.keys())[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ class DataPortalExchangeBase(DataPortal):
|
||||
return pd.concat(df_list)
|
||||
|
||||
else:
|
||||
exchange = self.exchanges[exchange_assets.keys()[0]]
|
||||
exchange = self.exchanges[list(exchange_assets.keys())[0]]
|
||||
return self.get_exchange_history_window(
|
||||
exchange,
|
||||
assets,
|
||||
@@ -165,8 +165,8 @@ class DataPortalExchangeBase(DataPortal):
|
||||
|
||||
exchange_assets[asset.exchange].append(asset)
|
||||
|
||||
if len(exchange_assets.keys()) == 1:
|
||||
exchange = self.exchanges[exchange_assets.keys()[0]]
|
||||
if len(list(exchange_assets.keys())) == 1:
|
||||
exchange = self.exchanges[list(exchange_assets.keys())[0]]
|
||||
return self.get_exchange_spot_value(
|
||||
exchange, assets, field, dt, data_frequency)
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class Exchange:
|
||||
self.request_cpt[now] = 0
|
||||
return True
|
||||
|
||||
cpt_date = self.request_cpt.keys()[0]
|
||||
cpt_date = list(self.request_cpt.keys())[0]
|
||||
cpt = self.request_cpt[cpt_date]
|
||||
|
||||
if now > cpt_date + timedelta(minutes=1):
|
||||
@@ -167,8 +167,10 @@ class Exchange:
|
||||
asset = self.assets[key]
|
||||
|
||||
if not asset:
|
||||
supported_symbols = [pair.symbol.encode('utf-8') for pair in
|
||||
self.assets.values()]
|
||||
supported_symbols = [
|
||||
pair.symbol for pair in list(self.assets.values())
|
||||
]
|
||||
|
||||
raise SymbolNotFoundOnExchange(
|
||||
symbol=symbol,
|
||||
exchange=self.name.title(),
|
||||
@@ -552,7 +554,7 @@ class Exchange:
|
||||
portfolio.starting_cash = portfolio.cash
|
||||
|
||||
if portfolio.positions:
|
||||
assets = portfolio.positions.keys()
|
||||
assets = list(portfolio.positions.keys())
|
||||
tickers = self.tickers(assets)
|
||||
|
||||
portfolio.positions_value = 0.0
|
||||
|
||||
@@ -113,7 +113,7 @@ class ExchangeTradingAlgorithmBase(TradingAlgorithm):
|
||||
else self.sim_params.end_session
|
||||
|
||||
if exchange_name is None:
|
||||
exchange = self.exchanges.values()[0]
|
||||
exchange = list(self.exchanges.values())[0]
|
||||
else:
|
||||
exchange = self.exchanges[exchange_name]
|
||||
|
||||
@@ -524,7 +524,7 @@ class ExchangeTradingAlgorithmLive(ExchangeTradingAlgorithmBase):
|
||||
self.add_pnl_stats(minute_stats)
|
||||
if self.recorded_vars:
|
||||
self.add_custom_signals_stats(minute_stats)
|
||||
recorded_cols = self.recorded_vars.keys()
|
||||
recorded_cols = list(self.recorded_vars.keys())
|
||||
else:
|
||||
recorded_cols = None
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ class ExchangeBundle:
|
||||
period_start, period_end = get_month_start_end(dt)
|
||||
asset_start_month, _ = get_month_start_end(asset_start)
|
||||
|
||||
if asset_start_month > period_start:
|
||||
if asset.start_date > period_start:
|
||||
dt += timedelta(days=1)
|
||||
continue
|
||||
|
||||
@@ -371,7 +371,7 @@ class ExchangeBundle:
|
||||
period_start, period_end = get_year_start_end(dt)
|
||||
asset_start_year, _ = get_year_start_end(asset_start)
|
||||
|
||||
if asset_start_year > period_start:
|
||||
if asset.start_date > period_start:
|
||||
dt += timedelta(days=1)
|
||||
continue
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ from catalyst.errors import ZiplineError
|
||||
|
||||
def silent_except_hook(exctype, excvalue, exctraceback):
|
||||
if exctype in [PricingDataBeforeTradingError, PricingDataNotLoadedError,
|
||||
SymbolNotFoundOnExchange, NoDataAvailableOnExchange,
|
||||
ExchangeAuthEmpty ]:
|
||||
SymbolNotFoundOnExchange, NoDataAvailableOnExchange,
|
||||
ExchangeAuthEmpty]:
|
||||
fn = traceback.extract_tb(exctraceback)[-1][0]
|
||||
ln = traceback.extract_tb(exctraceback)[-1][1]
|
||||
print "Error traceback: {1} (line {2})\n" \
|
||||
"{0.__name__}: {3}".format(exctype, fn, ln, excvalue)
|
||||
print("Error traceback: {1} (line {2})\n"
|
||||
"{0.__name__}: {3}".format(exctype, fn, ln, excvalue))
|
||||
else:
|
||||
sys.__excepthook__(exctype, excvalue, exctraceback)
|
||||
|
||||
@@ -214,7 +214,9 @@ class PricingDataNotLoadedError(ZiplineError):
|
||||
class ApiCandlesError(ZiplineError):
|
||||
msg = ('Unable to fetch candles from the remote API: {error}.').strip()
|
||||
|
||||
|
||||
class NoDataAvailableOnExchange(ZiplineError):
|
||||
msg = ('Requested data for trading pair {symbol} is not available on exchange {exchange} '
|
||||
'in `{data_frequency}` frequency at this time. '
|
||||
'Check `http://enigma.co/catalyst/status` for market coverage.').strip()
|
||||
msg = (
|
||||
'Requested data for trading pair {symbol} is not available on exchange {exchange} '
|
||||
'in `{data_frequency}` frequency at this time. '
|
||||
'Check `http://enigma.co/catalyst/status` for market coverage.').strip()
|
||||
|
||||
@@ -42,7 +42,9 @@ def get_exchange_symbols(exchange_name, environ=None):
|
||||
filename = get_exchange_symbols_filename(exchange_name)
|
||||
|
||||
if not os.path.isfile(filename) or \
|
||||
pd.Timedelta(pd.Timestamp('now', tz='UTC') - last_modified_time(filename)).days > 1:
|
||||
pd.Timedelta(pd.Timestamp('now',
|
||||
tz='UTC') - last_modified_time(
|
||||
filename)).days > 1:
|
||||
download_exchange_symbols(exchange_name, environ)
|
||||
|
||||
if os.path.isfile(filename):
|
||||
@@ -67,9 +69,11 @@ def get_exchange_auth(exchange_name, environ=None):
|
||||
else:
|
||||
data = dict(name=exchange_name, key='', secret='')
|
||||
with open(filename, 'w') as f:
|
||||
json.dump(data, f, sort_keys=False, indent=2, separators=(',', ':'))
|
||||
json.dump(data, f, sort_keys=False, indent=2,
|
||||
separators=(',', ':'))
|
||||
return data
|
||||
|
||||
|
||||
def get_algo_folder(algo_name, environ=None):
|
||||
if not environ:
|
||||
environ = os.environ
|
||||
@@ -163,6 +167,7 @@ def get_exchange_minute_writer_root(exchange_name, environ=None):
|
||||
|
||||
return minute_data_folder
|
||||
|
||||
|
||||
def get_exchange_bundles_folder(exchange_name, environ=None):
|
||||
exchange_folder = get_exchange_folder(exchange_name, environ)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ log = Logger('Poloniex', level=LOG_LEVEL)
|
||||
|
||||
class Poloniex(Exchange):
|
||||
def __init__(self, key, secret, base_currency, portfolio=None):
|
||||
self.api = Poloniex_api(key=key, secret=secret.encode('UTF-8'))
|
||||
self.api = Poloniex_api(key=key, secret=secret)
|
||||
self.name = 'poloniex'
|
||||
self.assets = {}
|
||||
self.load_assets()
|
||||
@@ -119,9 +119,9 @@ class Poloniex(Exchange):
|
||||
return order, executed_price
|
||||
|
||||
def get_balances(self):
|
||||
log.debug('retrieving wallets balances')
|
||||
balances = self.api.returnbalances()
|
||||
try:
|
||||
balances = self.api.returnbalances()
|
||||
log.debug('retrieving wallets balances')
|
||||
except Exception as e:
|
||||
log.debug(e)
|
||||
raise ExchangeRequestError(error=e)
|
||||
|
||||
@@ -19,19 +19,25 @@ class Poloniex_api(object):
|
||||
self.max_requests_per_second = 6
|
||||
self.request_cpt = dict()
|
||||
|
||||
self.public = ['returnTicker', 'return24Volume', 'returnOrderBook',
|
||||
'returnTradeHistory', 'returnChartData',
|
||||
'returnCurrencies', 'returnLoanOrders']
|
||||
self.trading = ['returnBalances','returnCompleteBalances','returnDepositAddresses',
|
||||
'generateNewAddress','returnDepositsWithdrawals','returnOpenOrders',
|
||||
'returnTradeHistory','returnOrderTrades',
|
||||
self.public = ['returnTicker', 'return24Volume', 'returnOrderBook',
|
||||
'returnTradeHistory', 'returnChartData',
|
||||
'returnCurrencies', 'returnLoanOrders']
|
||||
self.trading = ['returnBalances', 'returnCompleteBalances',
|
||||
'returnDepositAddresses',
|
||||
'generateNewAddress', 'returnDepositsWithdrawals',
|
||||
'returnOpenOrders',
|
||||
'returnTradeHistory', 'returnOrderTrades',
|
||||
'buy', 'sell', 'cancelOrder', 'moveOrder',
|
||||
'withdraw', 'returnFeeInfo','returnAvailableAccountBalances',
|
||||
'withdraw', 'returnFeeInfo',
|
||||
'returnAvailableAccountBalances',
|
||||
'returnTradableBalances', 'transferBalance',
|
||||
'returnMarginAccountSummary','marginBuy','marginSell',
|
||||
'getMarginPosition', 'closeMarginPosition','createLoanOffer',
|
||||
'cancelLoanOffer','returnOpenLoanOffers','returnActiveLoans',
|
||||
'returnLendingHistory','toggleAutoRenew']
|
||||
'returnMarginAccountSummary', 'marginBuy',
|
||||
'marginSell',
|
||||
'getMarginPosition', 'closeMarginPosition',
|
||||
'createLoanOffer',
|
||||
'cancelLoanOffer', 'returnOpenLoanOffers',
|
||||
'returnActiveLoans',
|
||||
'returnLendingHistory', 'toggleAutoRenew']
|
||||
|
||||
def ask_request(self):
|
||||
"""
|
||||
@@ -50,7 +56,7 @@ class Poloniex_api(object):
|
||||
self.request_cpt[now] = 0
|
||||
return True
|
||||
|
||||
cpt_date = self.request_cpt.keys()[0]
|
||||
cpt_date = list(self.request_cpt.keys())[0]
|
||||
cpt = self.request_cpt[cpt_date]
|
||||
|
||||
if now > cpt_date + 1:
|
||||
@@ -59,9 +65,8 @@ class Poloniex_api(object):
|
||||
return True
|
||||
|
||||
if cpt >= self.max_requests_per_second:
|
||||
|
||||
log.debug('max requests 6 reached, sleeping for 1 seconds')
|
||||
sleep(1)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
now = time.time()
|
||||
self.request_cpt = dict()
|
||||
@@ -73,18 +78,23 @@ class Poloniex_api(object):
|
||||
def query(self, method, req={}):
|
||||
|
||||
if method in self.public:
|
||||
url = 'https://poloniex.com/public?command=' + method + '&' + urllib.parse.urlencode(req)
|
||||
url = 'https://poloniex.com/public?command=' + method + '&' + \
|
||||
urllib.parse.urlencode(req)
|
||||
headers = {}
|
||||
post_data = None
|
||||
elif method in self.trading:
|
||||
url = 'https://poloniex.com/tradingApi'
|
||||
req['command'] = method
|
||||
req['nonce'] = int(time.time()*1000)
|
||||
post_data = urllib.parse.urlencode(req)
|
||||
signature = hmac.new(self.secret, post_data, hashlib.sha512).hexdigest()
|
||||
headers = { 'Sign': signature, 'Key': self.key}
|
||||
req['nonce'] = int(time.time() * 1000)
|
||||
post_data = urllib.parse.urlencode(req)
|
||||
|
||||
signature = hmac.new(self.secret.encode('utf-8'),
|
||||
post_data.encode('utf-8'),
|
||||
hashlib.sha512).hexdigest()
|
||||
headers = {'Sign': signature, 'Key': self.key}
|
||||
else:
|
||||
raise ValueError('Method "' + method + '" not found in neither the Public API or Trading API endpoints')
|
||||
raise ValueError(
|
||||
'Method "' + method + '" not found in neither the Public API or Trading API endpoints')
|
||||
|
||||
self.ask_request()
|
||||
req = urllib.request.Request(url, data=post_data, headers=headers)
|
||||
@@ -100,15 +110,17 @@ class Poloniex_api(object):
|
||||
return self.query('returnOrderBook', {'currencyPair': market})
|
||||
|
||||
def returntradehistory(self, market, start=None, end=None):
|
||||
if(start is not None and end is not None):
|
||||
return self.query('returntradehistory',
|
||||
{'currencyPair': market, 'start': start, 'end': end })
|
||||
if (start is not None and end is not None):
|
||||
return self.query('returntradehistory',
|
||||
{'currencyPair': market, 'start': start,
|
||||
'end': end})
|
||||
else:
|
||||
return self.query('returntradehistory', {'currencyPair': market })
|
||||
return self.query('returntradehistory', {'currencyPair': market})
|
||||
|
||||
def returnchartdata(self, market, period, start, end=9999999999):
|
||||
return self.query('returnChartData', {'currencyPair': market, 'period': period,
|
||||
'start': start, 'end': end})
|
||||
return self.query('returnChartData',
|
||||
{'currencyPair': market, 'period': period,
|
||||
'start': start, 'end': end})
|
||||
|
||||
def returncurrencies(self):
|
||||
return self.query('returnCurrencies', {})
|
||||
@@ -120,7 +132,7 @@ class Poloniex_api(object):
|
||||
return self.query('returnBalances')
|
||||
|
||||
def returncompletebalances(self, account):
|
||||
if(account):
|
||||
if (account):
|
||||
return self.query('returnCompleteBalances', {'account': account})
|
||||
else:
|
||||
return self.query('returnCompleteBalances')
|
||||
@@ -132,43 +144,54 @@ class Poloniex_api(object):
|
||||
return self.query('generateNewAddress', {'currency': currency})
|
||||
|
||||
def returnDepositsWithdrawals(self, start, end):
|
||||
return self.query('returnDepositsWithdrawals', {'start': start, 'end': end})
|
||||
return self.query('returnDepositsWithdrawals',
|
||||
{'start': start, 'end': end})
|
||||
|
||||
def returnopenorders(self, market):
|
||||
return self.query('returnOpenOrders', {'currencyPair': market})
|
||||
|
||||
def returntradehistory(self, market):
|
||||
#TODO: optional start and/or end and limit
|
||||
# TODO: optional start and/or end and limit
|
||||
return self.query('returnTradeHistory', {'currencyPair': market})
|
||||
|
||||
def returnordertrades(self, ordernumber):
|
||||
return self.query('returnOrderTrades', {'orderNumber': ordernumber})
|
||||
|
||||
def buy(self, market, amount, rate, fillorkill=0, immediateorcancel=0, postonly=0):
|
||||
if(fillorkill):
|
||||
return self.query('buy', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
def buy(self, market, amount, rate, fillorkill=0, immediateorcancel=0,
|
||||
postonly=0):
|
||||
if (fillorkill):
|
||||
return self.query('buy', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'fillOrKill': fillorkill, })
|
||||
elif(immediateorcancel):
|
||||
return self.query('buy', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
elif (immediateorcancel):
|
||||
return self.query('buy', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'immediateOrCancel': immediateorcancel, })
|
||||
elif(postonly):
|
||||
return self.query('buy', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
elif (postonly):
|
||||
return self.query('buy', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'postOnly': postonly, })
|
||||
else:
|
||||
return self.query('buy', {'currencyPair': market, 'rate':rate, 'amount': amount, })
|
||||
return self.query('buy', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount, })
|
||||
|
||||
def sell(self, market, amount, rate, fillorkill=0, immediateorcancel=0, postonly=0):
|
||||
if(fillorkill):
|
||||
return self.query('sell', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
'fillOrKill': fillorkill, })
|
||||
elif(immediateorcancel):
|
||||
return self.query('sell', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
'immediateOrCancel': immediateorcancel, })
|
||||
elif(postonly):
|
||||
return self.query('sell', {'currencyPair': market, 'rate':rate, 'amount': amount,
|
||||
'postOnly': postonly, })
|
||||
def sell(self, market, amount, rate, fillorkill=0, immediateorcancel=0,
|
||||
postonly=0):
|
||||
if (fillorkill):
|
||||
return self.query('sell', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'fillOrKill': fillorkill, })
|
||||
elif (immediateorcancel):
|
||||
return self.query('sell', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'immediateOrCancel': immediateorcancel, })
|
||||
elif (postonly):
|
||||
return self.query('sell', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount,
|
||||
'postOnly': postonly, })
|
||||
else:
|
||||
return self.query('sell', {'currencyPair': market, 'rate':rate, 'amount': amount, })
|
||||
return self.query('sell', {'currencyPair': market, 'rate': rate,
|
||||
'amount': amount, })
|
||||
|
||||
def cancelorder(self, ordernumber):
|
||||
return self.query('cancelOrder', {'orderNumber': ordernumber})
|
||||
@@ -180,4 +203,3 @@ class Poloniex_api(object):
|
||||
|
||||
def returnfeeinfo(self):
|
||||
return self.query('returnFeeInfo')
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
from unittest import TestCase
|
||||
from logbook import Logger
|
||||
from mock import patch, sentinel
|
||||
from catalyst.exchange.simple_clock import SimpleClock
|
||||
from catalyst.utils.calendars.trading_calendar import days_at_time
|
||||
from datetime import time
|
||||
from collections import defaultdict
|
||||
from catalyst.utils.calendars import get_calendar
|
||||
import pandas as pd
|
||||
|
||||
log = Logger('ExchangeClockTestCase')
|
||||
|
||||
|
||||
class ExchangeClockTestCase(TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.open_calendar = get_calendar("OPEN")
|
||||
|
||||
cls.sessions = pd.Timestamp.utcnow()
|
||||
|
||||
def setUp(self):
|
||||
self.internal_clock = None
|
||||
self.events = defaultdict(list)
|
||||
|
||||
def advance_clock(self, x):
|
||||
"""Mock function for sleep. Advances the internal clock by 1 min"""
|
||||
# The internal clock advance time must be 1 minute to match
|
||||
# MinutesSimulationClock's update frequency
|
||||
self.internal_clock += pd.Timedelta('1 min')
|
||||
|
||||
def get_clock(self, arg, *args, **kwargs):
|
||||
"""Mock function for pandas.to_datetime which is used to query the
|
||||
current time in RealtimeClock"""
|
||||
assert arg == "now"
|
||||
return self.internal_clock
|
||||
|
||||
def test_clock(self):
|
||||
with patch('catalyst.exchange.simple_clock.pd.to_datetime') as to_dt, \
|
||||
patch('catalyst.exchange.simple_clock.sleep') as sleep:
|
||||
clock = SimpleClock(sessions=self.sessions)
|
||||
to_dt.side_effect = self.get_clock
|
||||
sleep.side_effect = self.advance_clock
|
||||
start_time = pd.Timestamp.utcnow()
|
||||
self.internal_clock = start_time
|
||||
|
||||
events = list(clock)
|
||||
|
||||
# Event 0 is SESSION_START which always happens at 00:00.
|
||||
ts, event_type = events[1]
|
||||
pass
|
||||
Reference in New Issue
Block a user