def shell(ctx, **kwargs): ctx = process_algo_params(ctx, **kwargs) algorithm = ctx.algorithm algomodule = ctx.algomodule with LiveTraderAPI(algorithm): start_shell(algorithm, algomodule)
def run_smoke(algo, before_run_hook=None, pipeline_hook=None): fake_clock = clock.FaketimeClock() # fake_clock.rollback(1) be = backend.Backend(clock=fake_clock) a = Algorithm( initialize=getattr(algo, 'initialize', noop), handle_data=getattr(algo, 'handle_data', noop), before_trading_start=getattr(algo, 'before_trading_start', noop), backend=be, ) if pipeline_hook is not None: def _pipeline_output(name): return pipeline_hook.output(a, name) a.pipeline_output = _pipeline_output with LiveTraderAPI(a), \ patch('pylivetrader.executor.executor.RealtimeClock') as rc: def make_clock(*args, **kwargs): # may want to reconfigure clock return fake_clock rc.side_effect = make_clock if before_run_hook is not None: before_run_hook(a, be) a.run()
def run(ctx, algofile, backend, backend_config, data_frequency, statefile, zipline): if algofile is None or algofile == '': ctx.fail("must specify algo file with '-f' ") if not (Path(algofile).exists() and Path(algofile).is_file()): ctx.fail("couldn't find algofile '{}'".format(algofile)) functions = get_functions_by_path(algofile, use_translate=zipline) backend_options = None if backend_config is not None: backend_options = configloader.load_config(backend_config) algorithm = Algorithm( backend=backend, backend_options=backend_options, data_frequency=data_frequency, algoname=extract_filename(algofile), statefile=statefile, **functions, ) with LiveTraderAPI(algorithm): algorithm.run()
def initialize(self, *args, **kwargs): self._context_persistence_excludes = (list(self.__dict__.keys()) + ['executor']) self._state_store.load(self, self._algoname) with LiveTraderAPI(self): self._initialize(self, *args, **kwargs) self._state_store.save(self, self._algoname, self._context_persistence_excludes)
def run(self): algo = self.algo def every_bar(dt_to_use, current_data=self.current_data, handle_data=algo.event_manager.handle_data): # clear data portal cache. self.data_portal.cache_clear() # called every tick (minute or day). algo.on_dt_changed(dt_to_use) self.current_data.datetime = dt_to_use handle_data(algo, current_data, dt_to_use) algo.portfolio_needs_update = True algo.account_needs_update = True def once_a_day(midnight_dt, current_data=self.current_data, data_portal=self.data_portal): # set all the timestamps algo.on_dt_changed(midnight_dt) self.current_data.datetime = midnight_dt def on_exit(): # Remove references to algo, data portal, et al to break cycles # and ensure deterministic cleanup of these objects when the # simulation finishes. self.algo = None self.current_data = self.data_portal = None with ExitStack() as stack: stack.callback(on_exit) stack.enter_context(LiveTraderAPI(self.algo)) # runs forever for dt, action in self.clock: if action == BAR: every_bar(dt) elif action == SESSION_START: once_a_day(dt) elif action == BEFORE_TRADING_START_BAR: algo.on_dt_changed(dt) self.current_data.datetime = dt algo.before_trading_start(self.current_data)
def simulate_init_and_handle(algo): algo._assets_from_source = \ algo.asset_finder.retrieve_all(algo.asset_finder.sids) if not algo.initialized: algo.initialize() algo.initialized = True algo.executor = AlgorithmExecutor(algo, algo.data_portal) dt_to_use = pd.Timestamp('2018/08/13 9:30', tz='America/New_York').tz_convert('UTC') with LiveTraderAPI(algo): algo.on_dt_changed(dt_to_use) algo.executor.current_data.datetime = dt_to_use algo.before_trading_start(algo.executor.current_data) algo.handle_data(algo.executor.current_data)
def test_orders(): backend = alpaca.Backend('key-id', 'secret-key') with patch.object(backend, '_api') as _api: _api.list_assets.return_value = [ Asset({ 'id': 'bcfdb21a-760c-44a6-a3af-6264851b5c1b', 'asset_class': 'us_equity', 'exchange': 'NYSE', 'symbol': 'X', 'status': 'inactive', 'tradable': True }), Asset({ 'id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'asset_class': 'us_equity', 'exchange': 'NASDAQ', 'symbol': 'AAPL', 'status': 'active', 'tradable': True }), Asset({ 'id': '8688f60a-04c9-4740-8468-c0b994499f41', 'asset_class': 'us_equity', 'exchange': 'NYSE', 'symbol': 'BAC', 'status': 'active', 'tradable': True }), ] res = backend._symbols2assets(['AAPL']) assert len(res) == 1 _api.get_account.return_value = Account({ 'account_blocked': False, 'buying_power': '43.38', 'cash': '35036.18', 'cash_withdrawable': '43.38', 'created_at': '2018-08-27T18:33:56.812574Z', 'currency': 'USD', 'id': 'da66e4e6-db7e-4c2e-83ae-2e0cce995cf2', 'pattern_day_trader': False, 'portfolio_value': '49723.85', 'status': 'ACTIVE', 'trading_blocked': False, 'transfers_blocked': False }) res = backend.account assert res.buying_power < 100 _api.list_positions.return_value = [ Position({ 'asset_class': 'us_equity', 'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'avg_entry_price': '198', 'change_today': '0', 'cost_basis': '200', 'current_price': '200', 'exchange': 'NASDAQ', 'lastday_price': '200', 'market_value': '200', 'qty': '1', 'side': 'long', 'symbol': 'AAPL', 'unrealized_intraday_pl': '0', 'unrealized_intraday_plpc': '0', 'unrealized_pl': '2', 'unrealized_plpc': '0.01111' }), ] algo = Mock() algo._backend = backend algo.symbol = lambda x: backend._symbols2assets([x])[0] with LiveTraderAPI(algo): res = backend.portfolio assert res.cash > 30e3 assert len(res.positions) == 1 _api.list_orders.return_value = [ Order({ 'asset_class': 'us_equity', 'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'canceled_at': None, 'client_order_id': 'my_id_open', 'created_at': '2018-08-29T13:31:02.779465Z', 'expired_at': None, 'failed_at': None, 'filled_at': None, 'filled_avg_price': None, 'filled_qty': '0', 'id': '6abca255-bc5a-4688-a547-4bfd2c33a979', 'limit_price': '1.3', 'order_type': 'limit', 'qty': '3846', 'side': 'buy', 'status': 'new', 'stop_price': None, 'submitted_at': '2018-08-29T13:31:02.779394Z', 'symbol': 'AAPL', 'time_in_force': 'day', 'type': 'limit', 'updated_at': '2018-08-30T19:59:00.737786Z' }), Order({ 'asset_class': 'us_equity', 'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'canceled_at': None, 'client_order_id': 'my_id_failed', 'created_at': '2018-08-29T13:31:02.779465Z', 'expired_at': None, 'failed_at': '2018-08-29T13:31:02.779465Z', 'filled_at': None, 'filled_avg_price': None, 'filled_qty': '0', 'id': '6abca255-bc5a-4688-a547-4bfd2c33a979', 'limit_price': '1.3', 'order_type': 'limit', 'qty': '3846', 'side': 'buy', 'status': 'new', 'stop_price': None, 'submitted_at': '2018-08-29T13:31:02.779394Z', 'symbol': 'AAPL', 'time_in_force': 'day', 'type': 'limit', 'updated_at': '2018-08-30T19:59:00.737786Z' }), Order({ 'asset_class': 'us_equity', 'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'canceled_at': None, 'client_order_id': 'my_id_filled', 'created_at': '2018-08-29T13:31:02.779465Z', 'expired_at': None, 'failed_at': None, 'filled_at': '2018-08-29T13:31:02.779465Z', 'filled_avg_price': '200', 'filled_qty': '0', 'id': '6abca255-bc5a-4688-a547-4bfd2c33a979', 'limit_price': '1.3', 'order_type': 'limit', 'qty': '3846', 'side': 'buy', 'status': 'new', 'stop_price': None, 'submitted_at': '2018-08-29T13:31:02.779394Z', 'symbol': 'AAPL', 'time_in_force': 'day', 'type': 'limit', 'updated_at': '2018-08-30T19:59:00.737786Z' }), ] res = backend.orders # make sure order status is set correctly assert res['my_id_open']._status == ZP_ORDER_STATUS.OPEN assert res['my_id_failed']._status == ZP_ORDER_STATUS.REJECTED assert res['my_id_filled']._status == ZP_ORDER_STATUS.FILLED _api.submit_order.return_value = Order({ 'asset_class': 'us_equity', 'asset_id': '93f58d0b-6c53-432d-b8ce-2bad264dbd94', 'canceled_at': None, 'client_order_id': '439dca01703b4674a61a72713a612d24', 'created_at': '2018-08-29T13:31:01.710698Z', 'expired_at': None, 'failed_at': None, 'filled_at': None, 'filled_avg_price': None, 'filled_qty': '0', 'id': '2c366657-fdbd-4554-a14d-b19df2bf430c', 'limit_price': '2.05', 'order_type': 'limit', 'qty': '1', 'side': 'buy', 'status': 'new', 'stop_price': None, 'submitted_at': '2018-08-29T13:31:01.710651Z', 'symbol': 'AAPL', 'time_in_force': 'day', 'type': 'limit', 'updated_at': '2018-08-30T19:59:00.553942Z' }) aapl = algo.symbol('AAPL') # this response is not correct logically, but fine for testing res = backend.order(aapl, 1, MarketOrder()) assert res.limit > 1 # different order types should go through backend.order(aapl, 1, LimitOrder(limit_price=100)) backend.order(aapl, 1, StopOrder(stop_price=200)) backend.order(aapl, 1, StopLimitOrder(limit_price=100, stop_price=200)) backend.cancel_order('some-id') # order submission fail _api.submit_order.side_effect = APIError({'message': 'test'}) res = backend.order(aapl, -1, MarketOrder()) assert res is None
def run(ctx, **kwargs): ctx = process_algo_params(ctx, **kwargs) define_log_book_app(kwargs['timezone']) algorithm = ctx.algorithm with LiveTraderAPI(algorithm): algorithm.run(retry=ctx.retry)
def run(ctx, **kwargs): ctx = process_algo_params(ctx, **kwargs) algorithm = ctx.algorithm with LiveTraderAPI(algorithm): algorithm.run(retry=ctx.retry)
def run(self, retry=True): algo = self.algo def handle_retry(func): # decorator to log but swallow exception # if it is turned on. This is applied # only for periodic event. before_trading_start # is too critical to skip exception. def wrapper(*args, **kwargs): try: func(*args, **kwargs) except Exception as exc: if not retry: raise log.exception(exc) log.warning('Continuing execution') return wrapper @handle_retry def every_bar(dt_to_use, current_data=self.current_data, handle_data=algo.event_manager.handle_data): # clear data portal cache. self.data_portal.cache_clear() # called every tick (minute or day). algo.on_dt_changed(dt_to_use) self.current_data.datetime = dt_to_use handle_data(algo, current_data, dt_to_use) algo.portfolio_needs_update = True def once_a_day(midnight_dt, current_data=self.current_data, data_portal=self.data_portal): # set all the timestamps algo.on_dt_changed(midnight_dt) self.current_data.datetime = midnight_dt def on_exit(): # Remove references to algo, data portal, et al to break cycles # and ensure deterministic cleanup of these objects when the # simulation finishes. self.algo = None self.current_data = self.data_portal = None with ExitStack() as stack: stack.callback(on_exit) stack.enter_context(LiveTraderAPI(self.algo)) # runs forever for dt, action in self.clock: if action == BAR: every_bar(dt) elif action == SESSION_START: once_a_day(dt) elif action == BEFORE_TRADING_START_BAR: algo.on_dt_changed(dt) self.current_data.datetime = dt algo.before_trading_start(self.current_data)