Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sell_all() method has issue where it does not sell all positions and instead jacknifes because of variable "is_multileg" #608

Open
andrewtcrooks opened this issue Nov 2, 2024 · 4 comments

Comments

@andrewtcrooks
Copy link

/opt/homebrew/anaconda3/envs/stockbot/bin/python /Users/andrew/PyCharm/StockBot/stockbot/main.py
2024-11-01 19:41:28 | lumibot.credentials | INFO | .env file loaded from: /Users/andrew/PyCharm/StockBot/stockbot/.env
2024-11-01 19:41:30 | asyncio | INFO | [unknown] Waiting for the socket stream connection to be established,
method _stream_established must be called
2024-11-01 19:41:30 | alpaca.trading.stream | INFO | started trading stream
2024-11-01 19:41:30 | alpaca.trading.stream | INFO | starting trading websocket connection
2024-11-01 19:41:30,471 | asyncio | INFO | [Transformer Strategy] Strategy Transformer Strategy is initializing
2024-11-01 19:41:30,471 | asyncio | INFO | [Transformer Strategy] Executing the initialize lifecycle method
2024-11-01 19:41:30,472 | asyncio | INFO | [Transformer Strategy] Initializing Transformer Strategy...
2024-11-01 19:41:30,472 | asyncio | INFO | [Transformer Strategy] Getting historical prices for [AAPL, MSFT], 65 bars, minute
2024-11-01 19:41:30,474 | alpaca.trading.stream | INFO | connected to: wss://paper-api.alpaca.markets/stream
2024-11-01 19:41:30,835 | root | ERROR | Could not get any pricing data from Alpaca for AAPL, the DataFrame came back empty
2024-11-01 19:41:31,057 | root | ERROR | Could not get any pricing data from Alpaca for MSFT, the DataFrame came back empty
2024-11-01 19:41:31,057 | asyncio | INFO | [Transformer Strategy] No historical data fetched during initialization for AAPL.
2024-11-01 19:41:31,057 | asyncio | INFO | [Transformer Strategy] No historical data fetched during initialization for MSFT.
2024-11-01 19:41:31,888 | asyncio | INFO | [Transformer Strategy] Sleeping until the market opens
2024-11-01 19:41:32,229 | asyncio | INFO | [Transformer Strategy] Executing the before_market_opens lifecycle method
2024-11-01 19:41:32,565 | asyncio | INFO | [Transformer Strategy] Sleeping until the market opens
2024-11-01 19:41:32,638 | asyncio | INFO | [Transformer Strategy] Executing the before_starting_trading lifecycle method
2024-11-01 19:41:32,780 | asyncio | INFO | [Transformer Strategy] Strategy will check in again at: 2024-11-01 19:42:00
Traceback (most recent call last):
File "/Users/andrew/PyCharm/StockBot/stockbot/main.py", line 37, in
main()
File "/Users/andrew/PyCharm/StockBot/stockbot/main.py", line 34, in main
trader.run_all()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/traders/trader.py", line 140, in run_all
self._join_pool()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/traders/trader.py", line 229, in _join_pool
strategy_thread.join()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 287, in join
super(StrategyExecutor, self).join(timeout)
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/threading.py", line 1096, in join
self._wait_for_tstate_lock()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/threading.py", line 1116, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/traders/trader.py", line 241, in _stop_pool
strategy_thread.stop()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 284, in stop
self._on_abrupt_closing(KeyboardInterrupt())
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 517, in _on_abrupt_closing
self.strategy.on_abrupt_closing()
File "/Users/andrew/PyCharm/StockBot/stockbot/strategies/strategy_transformer/strategy.py", line 206, in on_abrupt_closing
self.sell_all()
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/strategies/strategy.py", line 1861, in sell_all
self.broker.sell_all(self.name, cancel_open_orders=cancel_open_orders, strategy=self, is_multileg=is_multileg)
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/brokers/broker.py", line 1044, in sell_all
self.submit_orders(orders, is_multileg=is_multileg)
File "/opt/homebrew/anaconda3/envs/stockbot/lib/python3.10/site-packages/lumibot/brokers/broker.py", line 965, in submit_orders
self._submit_orders(orders, **kwargs)
TypeError: Broker._submit_orders() got an unexpected keyword argument 'is_multileg'
2024-11-01 19:41:45,097 | asyncio | INFO | [Transformer Strategy] Executing the on_abrupt_closing event method
2024-11-01 19:41:45,097 | asyncio | INFO | [Transformer Strategy] Closed Abruptly! Selling all positions. Abandon ship!
2024-11-01 19:41:45,097 | asyncio | WARNING | [Transformer Strategy] Selling all positions for Transformer Strategy strategy

Process finished with exit code 1

@andrewtcrooks
Copy link
Author

And can anyone explain why this pulls data up until like 620PM PST and then suddenly stops until sometime before market opens the next day?

@andrewtcrooks
Copy link
Author

Putting this method inside my custom strategy seems to fix it for now so that it will actually sell off the positions when sell_all is called, even if it's doing it one at a time instead of in a multileg order. I look forward to that functionality being added

  def sell_all(self, cancel_open_orders: bool = True, is_multileg: bool = False):
      """
      Sell all current positions in the portfolio.

      :param is_multileg:
      :param cancel_open_orders: Cancel all open orders if True, leave all orders in place if False. Default is True.
      """
      if cancel_open_orders:
          self.cancel_open_orders()
      positions = self.get_positions()  # Access current positions
      self.log_message(f"Selling all positions...")
      for symbol, position in positions:
          quantity = position.quantity
          if quantity > 0:
              try:
                  # Place a market sell order for the entire quantity
                  self.sell_order(symbol, quantity)
                  self.log_message(f"Placed sell order for {quantity} shares of {symbol}.")
              except Exception as e:
                  self.log_message(f"Error selling {symbol}: {e}")

@andrewtcrooks
Copy link
Author

The source of the error is the _submit_order method inside broker.py not recognizing the "is_multileg" parameter being passed to it as kwargs.

This brings up an important question, why does the sell_all method need a "multileg" option? shouldn't it inherently sell all the assets with a multileg order to save on costs?

It sounds like fixing it might be an option but simply removing the redundancy might be more beneficial.

@andrewtcrooks
Copy link
Author

Best of luck, I'm switching over to QuantConnect so I can just worry about the strategy part. This has been an very educational experience though. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant