alpacahq / pylivetrader

Python live trade execution library with zipline interface.
https://pypi.org/project/pylivetrader/
Apache License 2.0
664 stars 195 forks source link

When outside market minutes, BarData's current(...) fails. #46

Open ttt733 opened 5 years ago

ttt733 commented 5 years ago

Reproduceable by calling order_target_percent(...) in an algorithm's before_trading_start() function. Not really an expected use case, but current() could be hit from other functions as well.

Stack trace:

Traceback (most recent call last):
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/bin/pylivetrader", line 11, in <module>
    load_entry_point('pylivetrader', 'console_scripts', 'pylivetrader')()
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/Users/tthackston/dev/alpaca/quantopian-fundamentals-examples/venv/lib/python3.7/site-packages/click/decorators.py", line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/__main__.py", line 134, in run
    algorithm.run(retry=ctx.retry)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 240, in run
    return self.executor.run(retry=retry)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/executor/executor.py", line 120, in run
    algo.before_trading_start(self.current_data)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 213, in before_trading_start
    self._before_trading_start(self, data)
  File "iex_quote_test.py", line 79, in before_trading_start
    rebalance(context)
  File "iex_quote_test.py", line 103, in rebalance
    order_target_percent(symbol(stock), weight)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/misc/api_context.py", line 62, in wrapped
    return getattr(algorithm, f.__name__)(*args, **kwargs)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 587, in order_target_percent
    amount = self._calculate_order_target_percent_amount(asset, target)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 804, in _calculate_order_target_percent_amount
    target_amount = self._calculate_order_percent_amount(asset, target)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 794, in _calculate_order_percent_amount
    return self._calculate_order_value_amount(asset, value)
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/algorithm.py", line 772, in _calculate_order_value_amount
    self.executor.current_data.current(asset, "price")
  File "/Users/tthackston/dev/alpaca/pylivetrader/pylivetrader/data/bardata.py", line 77, in current
    self.simulation_dt_func(),
AttributeError: 'BarData' object has no attribute 'simulation_dt_func'
spitzbubchen commented 4 years ago

Also getting this issue. Strange, it ran fine yesterday afternoon, but is producing this issue this morning...

[2020-05-01 13:52:55.709294] INFO: Algorithm: livetrader start running with backend = alpaca data-frequency = minute
6
[2020-05-01 13:52:57.302425] INFO: algo: 
Algorithm initialized variables:
 context.MaxCandidates 100
 LowVar 6
 HighVar 40
[2020-05-01 13:52:57.341151] INFO: pipeline_live.data.alpaca.pricing_loader: chart_range=65
[2020-05-01 13:53:05.107997] INFO: pipeline_live.data.alpaca.pricing_loader: chart_range=30
/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/zipline/pipeline/filters/filter.py:382: RuntimeWarning: invalid value encountered in less_equal
  return (lower_bounds <= data) & (data <= upper_bounds)
6
Traceback (most recent call last):
  File "/home/rod/Projects/alpaca/venv/bin/pylivetrader", line 11, in <module>
    sys.exit(main())
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/__main__.py", line 161, in run
    algorithm.run(retry=ctx.retry)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/algorithm.py", line 271, in run
    return self.executor.run(retry=retry)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/executor/executor.py", line 119, in run
    algo.before_trading_start(self.current_data)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/algorithm.py", line 244, in before_trading_start
    self._before_trading_start(self, data)
  File "long.py", line 202, in before_trading_start
    CurrPrice = float(data.current([stock], 'price'))
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/data/bardata.py", line 85, in current
    results = parallelize(fetch)(fetch_args)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/misc/parallel_utils.py", line 39, in wrapper
    task_result = task.result()
  File "/usr/lib/python3.6/concurrent/futures/_base.py", line 425, in result
    return self.__get_result()
  File "/usr/lib/python3.6/concurrent/futures/_base.py", line 384, in __get_result
    raise self._exception
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/rod/Projects/alpaca/venv/lib/python3.6/site-packages/pylivetrader/data/bardata.py", line 81, in fetch
    self.simulation_dt_func(),
AttributeError: 'BarData' object has no attribute 'simulation_dt_func'
spitzbubchen commented 4 years ago

This only pops up when I run the algo with pre-exisitng positions in my portfolio. If I sell all positions and then run the algo it runs fine.

mrmushfiq commented 4 years ago

I found a temporary fix which is to use get_barset() from python trading api and get Current Price from polygon. Just use the latest closing price in the minute data.

juania1-1529573 commented 4 years ago

Cool workaround @mrmushfiq, how would you convert: CurrPrice = float(data.current([stock], "price"))? I'm a bit confused on how you would import an instance of alpaca trading api into your pylivetrader program.

mrmushfiq commented 4 years ago

CurrPrice is just looking for float number. Doesn't matter where we get it from. Check this example from python trading api. https://github.com/alpacahq/alpaca-trade-api-python/blob/master/examples/overnight_hold.py . Read through line 30 to 50. you just need few lines of code from there to get the latest closing price.
You could also use any other source or library like piEX. Just pass stock.symbol . :)

for stock in context.portfolio.positions:
        barset = pass stock.symbol to get_barset like the overnight hold example
        then get the latest closing price.

PS. You will need toimport alpaca_trade_api as tradeapi and initiate the rest api at the begining of you code. Also set up the environment variables (API Keys) . Also see the read the ReadMe page. https://github.com/alpacahq/alpaca-trade-api-python

juania1-1529573 commented 4 years ago

Perfect, thanks for the help!