Giter VIP home page Giter VIP logo

lumibot's People

Contributors

calumharvey avatar canx avatar daniel-ltw avatar davidlatte avatar fovi-com avatar grzesir avatar ishapiro avatar jbrass avatar jeffreywinger55 avatar jimwhite avatar mattbsea avatar michaelcai avatar mrchaos avatar nathanccmiller avatar neilsmurphy avatar ohtarnishedone avatar red9811 avatar robertmacleod avatar slimbeji avatar trainedpro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lumibot's Issues

Options example is not working

The example given for options with AAPL is not working properly. Please help with that and can i use Nifty (indian market data) in this code.

Alpaca setup issue : cannot import name Bar

I followed all steps and I am using python 3.6.1
I created credentials.py and setup alpacaconfig class
class AlpacaConfig:
API_KEY = "XXXXX"
API_SECRET = "YYYY"
ENDPOINT = "https://paper-api.alpaca.markets"

Getting following error in alpaca_data.py -

File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\lumibot\data_sources_init_.py", line 1, in
from .alpaca_data import AlpacaData
File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\lumibot\data_sources\alpaca_data.py", line 7, in
from alpaca_trade_api.entity import Bar
ImportError: cannot import name 'Bar'

Backtest throws an error when trying to backtest at a date before the assets exist

When trying to backtest a strategy but the date is set before the asset exists then a confusing error is thrown. This error should more clearly state what the problem is and how to fix it.

The error:

2021-03-10 23:34:44,019: ERROR: single positional indexer is out-of-bounds
2021-03-10 23:34:44,023: ERROR: Traceback (most recent call last):
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 564, in run
    self._run_trading_session()
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 523, in _run_trading_session
    self.on_trading_iteration()
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/tools/decorators.py", line 64, in func_output
    frame, result = call_function_get_frame(func_input, *args, **kwargs)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/tools/decorators.py", line 24, in call_function_get_frame
    result = func(*args, **kwargs)
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day 8 - With Lumibot/debt_trading_strategy.py", line 59, in on_trading_iteration
    self.update_prices()
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day 8 - With Lumibot/debt_trading_strategy.py", line 114, in update_prices
    prices = self.get_last_prices(symbols)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 316, in get_last_prices
    return self.broker.get_last_prices(symbols)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/backtesting/backtesting_broker.py", line 208, in get_last_prices
    return self._data_source.get_last_prices(symbols)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/data_sources/data_source.py", line 151, in get_last_prices
    last_value = bars.df.iloc[0].close
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 879, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 1496, in _getitem_axis
    self._validate_integer(key, axis)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 1437, in _validate_integer
    raise IndexError("single positional indexer is out-of-bounds")
IndexError: single positional indexer is out-of-bounds

Steps to reproduce:

  1. Choose any strategy to backtest
  2. Set the backtesting start date to be datetime(1900, 1, 1)
  3. Run the backtest

Alpaca setup issue

I am getting following error in simple_start_alpaca.py : (I am using python 3.6.1 and installed latest alpaca api 1.3.0 using pip install )

File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\backtesting_init_.py", line 1, in
from .alpaca_backtesting import AlpacaBacktesting
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\backtesting\alpaca_backtesting.py", line 1, in
from lumibot.data_sources import AlpacaData
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\data_sources_init_.py", line 1, in
from .alpaca_data import AlpacaData
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\data_sources\alpaca_data.py", line 9, in
from lumibot.entities import Bars
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\entities_init_.py", line 1, in
from .asset import Asset, AssetsMapping
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\entities\asset.py", line 6, in
class Asset(BaseModel, frozen=True, extra='forbid'):
File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pydantic\main.py", line 324, in new
cls = super().new(mcs, name, bases, new_namespace, **kwargs)
TypeError: new() got an unexpected keyword argument 'frozen'

TypeError: 'NoneType' object does not support item assignment

When Lumibot is internally assigning a datetime, it appears to be None which creates issues. This issue is during paper trading regardless of the account's balance.

Code

from lumibot.strategies import Strategy
from lumibot.backtesting import YahooDataBacktesting
from lumibot.traders import Trader
from lumibot.brokers import Alpaca

import talib as ta
from config import ALPACA_CONFIG

class My_Strategy(Strategy):
	old_weight_dict = {}
	new_weight_dict = {}

	def initialize(self):
		self.minutes_before_opening = 0
		self.minutes_before_closing = 0
		self.sell_all()

	def on_trading_iteration(self):
		self.log_message(f'My_Strategy self.cash = {self.cash}$')

		self.new_weight_dict = {"INTC" : 7, "MSFT" : 7, "TXN" : 7, "AMD" : 7, "HPQ" : 7, "GE" : 7, "IBM" : 7}

		stocks_RSI = {"INTC" : 0, "MSFT" : 0, "COHU" : 0, "CGNX" : 0, "AMD" : 0, "ADSK" : 0, "AMAT" : 0, "TXN" : 0, "IBM" : 0, "GE" : 0, "HPQ" : 0, }
		
		for stock in stocks_RSI:
			dataframe = self.get_historical_prices("SPY", 200, "day").df["close"].interpolate(method="linear", limit_direction="both")

			stocks_RSI[stock] = ta.SMA(dataframe.pct_change(), 60)[-1]
		
		highest_RSIs = sorted(stocks_RSI.items(), key = lambda x: x[1], reverse=True)[:3]
		
		for stock, _ in highest_RSIs:
			self.new_weight_dict[stock] = min(self.new_weight_dict.get(stock, 0) + 17, 100)

		self.log_message(f"Old Dictionary: {str(self.old_weight_dict).replace(',', ' ')}		New Dictionary: {str(self.new_weight_dict).replace(',', ' ')}")

		for stock, weight in self.old_weight_dict.items():
			if stock not in self.new_weight_dict:
				price = self.get_last_price(stock)
				position = self.get_position(stock)
				if position is not None:
					order = self.get_selling_order(position)
					self.log_message(f"Sell Order: {stock} Sold {price * position.quantity}$.", color = "light_red")
					self.submit_order(order)

		# self.log_message(f"Current Cash Before Buying: {self.cash}$")

		for stock, weight in self.new_weight_dict.items():
			price = self.get_last_price(stock)

			if self.old_weight_dict == self.new_weight_dict:
				self.log_message(f"Dictionaries Are The Same {self.old_weight_dict} == {self.new_weight_dict}")
				quantity = self.cash * (weight / 100) // price

				self.log_message(f"Same Dictionary Order Balancing For {stock}")

				if quantity > 0:
					order = self.create_order(stock, quantity, "buy")
					self.log_message(f"Order Adjusted {stock} +{price * quantity}$")
					self.submit_order(order)

			elif stock in self.old_weight_dict:
				# self.log_message(f"{stock} is in the old dictionary. Available Cash: {self.cash}$")
				if weight > self.old_weight_dict[stock]:
					weight_difference = weight - self.old_weight_dict[stock]
					quantity = (self.cash * (weight_difference / 100)) // price

					self.log_message(f"Increase Order: {stock} Changed Order From {self.old_weight_dict[stock] * price}$ to {weight * price}$.", color = "light_green")
					self.log_message(f"Calculated Quantity: {quantity}")
					
					if quantity > 0 and self.cash >= price * quantity:
						order = self.create_order(stock, quantity, "buy")
						self.log_message(f"Buy Order: {stock} Bought {price * quantity}$.", color = "light_green")
						self.submit_order(order)

				elif weight < self.old_weight_dict[stock]:
					weight_difference = self.old_weight_dict[stock] - weight
					quantity = (self.cash * (weight_difference / 100)) // price

					self.log_message(f"Decrease Order: {stock} Changed Order From {self.old_weight_dict[stock] * price}$ to {weight * price}$.", color = "light_red")
					self.log_message(f"Calculated Quantity: {quantity}")
					
					if quantity > 0 and self.cash >= price * quantity:
						order = self.create_order(stock, quantity, "sell")
						self.log_message(f"Sell Order: {stock} Sold {price * quantity}$.", color = "light_red")
						self.submit_order(order)
			else:
				# self.log_message(f"{stock} Not in the old dictionary. Available Cash: {self.cash}$")
				quantity = (self.cash * (weight / 100)) // price

				self.log_message(f"Calculated Quantity: {quantity}")

				if quantity > 0 and self.cash >= price * quantity:
					order = self.create_order(stock, quantity, "buy")
					self.log_message(f"Buy Order: {stock} Bought {price * quantity}$.", color = "light_green")
					self.submit_order(order)

		self.old_weight_dict = self.new_weight_dict.copy()
		self.new_weight_dict.clear() # so that is it updated for the next turn
		# self.log_message(f"Cash On End Of Iteration: {self.cash}$")

	def trace_stats(self, context, snapshot_before):
		self.log_message(f"Ending Cash Value: {self.cash}$")
		self.log_message(f"Ending Portfolio Value: {self.portfolio_value}")


if __name__ == "__main__":
	broker = Alpaca(ALPACA_CONFIG)
	strategy = My_Strategy(broker=broker, sleeptime="10S", budget=10000)
	trader = Trader()

	trader.add_strategy(strategy)
	trader.run_all()

Logs

2023-08-01 20:18:47,791: root: INFO: My_Strategy : Executing the initialize lifecycle method
2023-08-01 20:18:47,791: root: WARNING: Strategy My_Strategy: sell all
2023-08-01 20:18:48,143: root: INFO: �[32mmarket order of | 754 GOOG sell | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:18:48,169: root: INFO: �[32mNew market order of | 754 GOOG sell | with status pending_new was submitted.�[0m
2023-08-01 20:18:48,801: root: INFO: Partial Fill Transaction: sell 25 of GOOG at $132.42 per share
2023-08-01 20:18:48,805: root: INFO: market order of | 754 GOOG sell | with status new was partially filled
2023-08-01 20:18:48,988: root: INFO: Partial Fill Transaction: sell 188 of GOOG at $132.42 per share
2023-08-01 20:18:48,998: root: INFO: market order of | 754 GOOG sell | with status partial_fill was partially filled
2023-08-01 20:18:49,631: root: INFO: Partial Fill Transaction: sell 55 of GOOG at $132.42 per share
2023-08-01 20:18:49,632: root: INFO: market order of | 754 GOOG sell | with status partial_fill was partially filled
2023-08-01 20:18:50,067: root: INFO: �[32mFilled Transaction: sell 486 of GOOG at 132.46000000 USD per share�[0m
2023-08-01 20:18:50,068: root: INFO: market order of | 754 GOOG sell | with status partial_fill was filled
2023-08-01 20:18:50,073: root: INFO: Position 0.000000 shares of GOOG liquidated
2023-08-01 20:18:50,729: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:18:50,729: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the before_starting_trading lifecycle method
2023-08-01 20:18:52,129: root: INFO: My_Strategy : Executing the on_trading_iteration lifecycle method
2023-08-01 20:18:52,129: root: INFO: My_Strategy : My_Strategy self.cash = 99873.22$
2023-08-01 20:18:52,130: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:58,113: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:58,684: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:59,256: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:59,845: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:00,413: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:00,973: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:01,540: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:02,104: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:02,704: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:03,273: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:03,843: root: INFO: My_Strategy : Old Dictionary: {}		New Dictionary: {'INTC': 24  'MSFT': 24  'TXN': 7  'AMD': 7  'HPQ': 7  'GE': 7  'IBM': 7  'COHU': 17}
2023-08-01 20:19:04,120: root: INFO: My_Strategy : Calculated Quantity: 674.0
2023-08-01 20:19:04,121: root: INFO: �[92mMy_Strategy : Buy Order: INTC Bought 23953.96$.�[0m
2023-08-01 20:19:04,398: root: INFO: �[32mmarket order of | 674 INTC buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:04,404: root: INFO: �[32mNew market order of | 674 INTC buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:04,449: root: INFO: My_Strategy : Calculated Quantity: 71.0
2023-08-01 20:19:04,450: root: INFO: �[92mMy_Strategy : Buy Order: MSFT Bought 23904.28$.�[0m
2023-08-01 20:19:04,734: root: INFO: �[32mmarket order of | 71 MSFT buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:04,734: root: INFO: �[32mFilled Transaction: buy 674 of INTC at 35.54000000 USD per share�[0m
2023-08-01 20:19:04,734: root: INFO: market order of | 674 INTC buy | with status new was filled
2023-08-01 20:19:04,743: root: INFO: �[32mNew market order of | 71 MSFT buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:04,760: root: INFO: My_Strategy : Calculated Quantity: 39.0
2023-08-01 20:19:04,760: root: INFO: �[92mMy_Strategy : Buy Order: TXN Bought 6957.795$.�[0m
2023-08-01 20:19:05,028: root: INFO: My_Strategy : Calculated Quantity: 60.0
2023-08-01 20:19:05,028: root: INFO: �[32mmarket order of | 39 TXN buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,029: root: INFO: �[92mMy_Strategy : Buy Order: AMD Bought 6973.2$.�[0m
2023-08-01 20:19:05,306: root: INFO: My_Strategy : Calculated Quantity: 213.0
2023-08-01 20:19:05,307: root: INFO: �[32mmarket order of | 60 AMD buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,308: root: INFO: �[92mMy_Strategy : Buy Order: HPQ Bought 6976.8150000000005$.�[0m
2023-08-01 20:19:05,308: root: INFO: �[32mNew market order of | 39 TXN buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:05,581: root: INFO: My_Strategy : Calculated Quantity: 62.0
2023-08-01 20:19:05,582: root: INFO: �[32mmarket order of | 213 HPQ buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,582: root: INFO: �[92mMy_Strategy : Buy Order: GE Bought 6968.18$.�[0m
2023-08-01 20:19:05,583: root: INFO: Partial Fill Transaction: buy 37 of MSFT at $336.65 per share
2023-08-01 20:19:05,585: root: INFO: market order of | 71 MSFT buy | with status new was partially filled
2023-08-01 20:19:05,860: root: INFO: My_Strategy : Calculated Quantity: 49.0
2023-08-01 20:19:05,861: root: INFO: �[32mmarket order of | 62 GE buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,861: root: INFO: �[92mMy_Strategy : Buy Order: IBM Bought 6976.62$.�[0m
2023-08-01 20:19:06,129: root: INFO: My_Strategy : Calculated Quantity: 390.0
2023-08-01 20:19:06,130: root: INFO: �[32mmarket order of | 49 IBM buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:06,130: root: INFO: �[92mMy_Strategy : Buy Order: COHU Bought 16945.5$.�[0m
2023-08-01 20:19:06,131: root: INFO: �[32mNew market order of | 60 AMD buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:06,131: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,132: root: INFO: My_Strategy : Executing the on_filled_order event method
2023-08-01 20:19:06,132: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Ending Cash Value: 63463.21000000001$
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Ending Portfolio Value: 99861.32
2023-08-01 20:19:06,133: root: ERROR: 'NoneType' object does not support item assignment
2023-08-01 20:19:06,134: root: ERROR: Traceback (most recent call last):
  File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 570, in run
    self._run_trading_session()
  File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 538, in _run_trading_session
    self._on_trading_iteration()
  File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 261, in func_output
    result = func_input(self, *args, **kwargs)
  File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 286, in func_output
    self._trace_stats(self._strategy_context, snapshot_before)
  File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 297, in _trace_stats
    result["datetime"] = self.strategy.get_datetime()
TypeError: 'NoneType' object does not support item assignment

Let me know if any further information is needed. I'd be happy to work on the issue if i get information on why this could be.

Options asset expiring at wrong time

For options asset, when the expiry date is mentioned (for ex: 29th Sept 2021), the option is expiring on 29th sept at 9:31 AM. Instead it had to expire on 29th Sept at 3:59 PM.

Strategies do not actually sleep when using self.await_market_to_close()

Every strategy that has the code self.await_market_to_close() no longer actually sleeps until the next trading day, instead, the on_trading_iteration() keeps executing after the set sleep time. Here's the logs:

2021-03-11 00:14:56,159: INFO: Strategy DebtTrading: Executing the initialize lifecycle method
2021-03-11 00:14:57,905: INFO: Strategy DebtTrading: Executing the before_market_opens lifecycle method
2021-03-11 00:14:58,060: INFO: Sleeping until the market opens
Progress |████████████████████████████████████████████████████████████████████████████████████████| 100.00% Complete2021-03-11 00:14:58,060: INFO: Current backtesting datetime 2021-03-11 01:15:01.869044
2021-03-11 00:14:58,061: INFO: Strategy DebtTrading: Executing the before_starting_trading lifecycle method
2021-03-11 00:14:58,127: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:14:58,128: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:14:58,129: INFO: Debt level: 0.017681222903851657
2021-03-11 00:14:58,129: INFO: Using the normal_ratio: 0.6
2021-03-11 00:14:58,816: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:14:58,817: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:14:58,971: INFO: market order of | 77 SPY buy | with status accepted was sent to broker alpaca
2021-03-11 00:14:59,200: INFO: market order of | 142 TLT buy | with status accepted was sent to broker alpaca
2021-03-11 00:14:59,201: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:14:59,201: INFO: Sleeping until next trading day
2021-03-11 00:14:59,347: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:15:59,349: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:15:59,351: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:15:59,352: INFO: Debt level: 0.017681222903851657
2021-03-11 00:15:59,352: INFO: Using the normal_ratio: 0.6
2021-03-11 00:15:59,475: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:15:59,475: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:15:59,475: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:15:59,475: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:15:59,475: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:15:59,475: INFO: Sleeping until next trading day
2021-03-11 00:15:59,712: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:16:59,718: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:16:59,719: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:16:59,720: INFO: Debt level: 0.017681222903851657
2021-03-11 00:16:59,721: INFO: Using the normal_ratio: 0.6
2021-03-11 00:16:59,901: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:16:59,902: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:16:59,902: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:16:59,902: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:16:59,902: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:16:59,902: INFO: Sleeping until next trading day
2021-03-11 00:17:00,178: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:18:00,179: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:18:00,180: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:18:00,181: INFO: Debt level: 0.017681222903851657
2021-03-11 00:18:00,181: INFO: Using the normal_ratio: 0.6
2021-03-11 00:18:00,298: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:18:00,298: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:18:00,298: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:18:00,298: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:18:00,299: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:18:00,299: INFO: Sleeping until next trading day
2021-03-11 00:18:00,514: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:19:00,515: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:19:00,516: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:19:00,517: INFO: Debt level: 0.017681222903851657
2021-03-11 00:19:00,517: INFO: Using the normal_ratio: 0.6
2021-03-11 00:19:00,695: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:19:00,695: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:19:00,695: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:19:00,695: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:19:00,695: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:19:00,696: INFO: Sleeping until next trading day
2021-03-11 00:19:00,897: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:20:00,898: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:20:00,899: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:20:00,901: INFO: Debt level: 0.017681222903851657
2021-03-11 00:20:00,901: INFO: Using the normal_ratio: 0.6
2021-03-11 00:20:01,090: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:20:01,091: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:20:01,091: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:20:01,091: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:20:01,091: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:20:01,091: INFO: Sleeping until next trading day
2021-03-11 00:20:01,331: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:21:01,333: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:21:01,334: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:21:01,335: INFO: Debt level: 0.017681222903851657
2021-03-11 00:21:01,336: INFO: Using the normal_ratio: 0.6
2021-03-11 00:21:01,476: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:21:01,477: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:21:01,477: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:21:01,477: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:21:01,477: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:21:01,477: INFO: Sleeping until next trading day
2021-03-11 00:21:01,722: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:22:01,723: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:22:01,723: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:22:01,724: INFO: Debt level: 0.017681222903851657
2021-03-11 00:22:01,725: INFO: Using the normal_ratio: 0.6
2021-03-11 00:22:01,939: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:22:01,939: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:22:01,939: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:22:01,939: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:22:01,939: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:22:01,939: INFO: Sleeping until next trading day
2021-03-11 00:22:02,388: INFO: Strategy DebtTrading: Sleeping for 60 seconds

This is during a time when the market is closed. Previously in version 0.0.6 the program would actually sleep and wait until tomorrow, now it instead keeps executing on_trading_iteration() every 60 seconds.

Order.is_option() doesn't detect 'option' type correctly

A clear option order isn't being properly detected as "option" by the is_option() method.

Test Case:

from lumibot.entities import Asset, Order

asset = Asset("SPY", asset_type="option")
order = Order(asset=asset, quantity=10, side="buy", strategy='abc')
order.is_option()

> False

It's an issue with the underlying code checking order.sec_type incorrectly.

Lumibot Examples Do Not Work

The examples provided in Lumibot do not work with live trading when adding on statements such as printing the value of self.cash. Errors are generated and the bot crashes.

Does not work

This code does not work.

Python 3.10.11

2023-05-31 10:08:41,412: root: INFO: Strangle : Executing the initialize lifecycle method
Exception in thread Strangle:
Traceback (most recent call last):
  File "/Users/petrov/.pyenv/versions/3.10.11/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 559, in run
    self._initialize()
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 261, in func_output
    result = func_input(self, *args, **kwargs)
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 316, in _initialize
    self.strategy.initialize(**safe_params_to_pass)
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/examples/strangle.py", line 74, in initialize
    self.create_trading_pair(symbol)
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/examples/strangle.py", line 303, in create_trading_pair
    self.trading_pairs[self.create_asset(symbol, asset_type="stock")] = {
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy.py", line 2476, in create_asset
    return Asset(
  File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/entities/asset.py", line 125, in __init__
    super().__init__(symbol=symbol, asset_type=asset_type, **data)
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Asset
strike
  value is not a valid float (type=type_error.float)

BUG: pip install downloading all ccxt versions.

When attempting "pip install lumibot", it begins installing all version of the "ccxt" dependency. I imagine this could be fixed by setting a static version number in the requirements file.

Backtest Sample: TypeError: 'NoneType' object is not callable (Numpy getlimits.py)

Trying the buy AAPL on the first day and hold, I'm getting an exception when the tearsheet is being created, I think?

It's running fine on a Linux device with Python 3.8, but not on MS Windows Python 3.10?

Both have the same versions of the various packages, from what I can make out.

(The warning isn't relevant)

Exception:

C:\Python310\lib\site-packages\lumibot\tools\indicators.py:209: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  _df2[benchmark_name][0] = 1
Traceback (most recent call last):
  File "C:\Python310\lib\site-packages\numpy\core\getlimits.py", line 460, in __new__
    dtype = numeric.dtype(dtype)
TypeError: 'NoneType' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "E:\source\InvestorSignals\LumiBot\buyOnce.py", line 23, in <module>
    MyStrategy.backtest(
  File "C:\Python310\lib\site-packages\lumibot\strategies\_strategy.py", line 942, in backtest
    strategy.tearsheet(
  File "C:\Python310\lib\site-packages\lumibot\strategies\_strategy.py", line 645, in tearsheet
    create_tearsheet(
  File "C:\Python310\lib\site-packages\lumibot\tools\indicators.py", line 382, in create_tearsheet
    qs.reports.html(
  File "C:\Python310\lib\site-packages\quantstats\reports.py", line 142, in html
    _plots.returns(returns, benchmark, grayscale=grayscale,
  File "C:\Python310\lib\site-packages\quantstats\_plotting\wrappers.py", line 278, in returns
    fig = _core.plot_timeseries(returns, benchmark, title,
  File "C:\Python310\lib\site-packages\quantstats\_plotting\core.py", line 255, in plot_timeseries
    fig.autofmt_xdate()
  File "C:\Python310\lib\site-packages\matplotlib\figure.py", line 274, in autofmt_xdate
    for label in self.axes[0].get_xticklabels(which=which):
  File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 75, in wrapper
    return get_method(self)(*args, **kwargs)
  File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1242, in get_ticklabels
    return self.get_majorticklabels()
  File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1201, in get_majorticklabels
    ticks = self.get_major_ticks()
  File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1371, in get_major_ticks
    numticks = len(self.get_majorticklocs())
  File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1277, in get_majorticklocs
    return self.major.locator()
  File "C:\Python310\lib\site-packages\matplotlib\dates.py", line 1338, in __call__
    dmin, dmax = self.viewlim_to_dt()
  File "C:\Python310\lib\site-packages\matplotlib\dates.py", line 1120, in viewlim_to_dt
    vmin, vmax = self.axis.get_view_interval()
  File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1987, in getter
    return getattr(getattr(self.axes, lim_name), attr_name)
  File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 781, in viewLim
    self._unstale_viewLim()
  File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 776, in _unstale_viewLim
    self.autoscale_view(**{f"scale{name}": scale
  File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 2932, in autoscale_view
    handle_single_axis(
  File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 2928, in handle_single_axis
    x0, x1 = locator.view_limits(x0, x1)
  File "C:\Python310\lib\site-packages\matplotlib\ticker.py", line 1662, in view_limits
    return mtransforms.nonsingular(vmin, vmax)
  File "C:\Python310\lib\site-packages\matplotlib\transforms.py", line 2880, in nonsingular
    if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny:
  File "C:\Python310\lib\site-packages\numpy\core\getlimits.py", line 463, in __new__
    dtype = numeric.dtype(type(dtype))
TypeError: 'NoneType' object is not callable

The actual backtest code is.

from datetime import datetime

from lumibot.backtesting import YahooDataBacktesting
from lumibot.strategies import Strategy


# A simple strategy that buys AAPL on the first day and hold it
class MyStrategy(Strategy):
    def on_trading_iteration(self):
        if self.first_iteration:
            aapl_price = self.get_last_price("AAPL")
            quantity = self.portfolio_value // aapl_price
            order = self.create_order("AAPL", quantity, "buy")
            self.submit_order(order)


# Pick the dates that you want to start and end your backtest
# and the allocated budget
backtesting_start = datetime(2020, 11, 1)
backtesting_end = datetime(2020, 12, 31)

# Run the backtest
MyStrategy.backtest(
    YahooDataBacktesting,
    backtesting_start,
    backtesting_end,
)

I'm not sure too sure where to look on this one.

Github actions

Do you have any interest in someone adding GH actions for running tests/linters etc?

new

My name is Luis, I'm a big-data machine-learning developer, I'm a fan of your work, and I usually check your updates.

I was afraid that my savings would be eaten by inflation. I have created a powerful tool that based on past technical patterns (volatility, moving averages, statistics, trends, candlesticks, support and resistance, stock index indicators).
All the ones you know (RSI, MACD, STOCH, Bolinger Bands, SMA, DEMARK, Japanese candlesticks, ichimoku, fibonacci, williansR, balance of power, murrey math, etc) and more than 200 others.

The tool creates prediction models of correct trading points (buy signal and sell signal, every stock is good traded in time and direction).
For this I have used big data tools like pandas python, stock market libraries like: tablib, TAcharts ,pandas_ta... For data collection and calculation.
And powerful machine-learning libraries such as: Sklearn.RandomForest , Sklearn.GradientBoosting, XGBoost, Google TensorFlow and Google TensorFlow LSTM.

With the models trained with the selection of the best technical indicators, the tool is able to predict trading points (where to buy, where to sell) and send real-time alerts to Telegram or Mail. The points are calculated based on the learning of the correct trading points of the last 2 years (including the change to bear market after the rate hike).

I think it could be useful to you, to improve, I would like to share it with you, and if you are interested in improving and collaborating I am also willing, and if not file it in the box.

If tou want, Please read the readme , and in case of any problem you can contact me ,
If you are convinced try to install it with the documentation.
https://github.com/Leci37/stocks-Machine-learning-RealTime-telegram/tree/develop I appreciate the feedback

Create Pandas data frames formaters

Build shortcuts to put pandas dataframes to a standard format and avoid code duplicates like

df["price_change"] = df["close"].pct_change()
df["momentum"] = df["close"].pct_change(periods=momentum_length)

Enforce Python version

I had a hard time running the project, it raises an exception running with Python 3.6, 3.8 and 3.10 would be nice to have something that specifies/enforce the Python version required.

Intraday Momentum not working for backtesting

This is the CLI output:

INFO:root:Fetching past trading days
INFO:root:Waiting for the socket stream connection to be established, 
            method _stream_established must be called
INFO:root:Risk Free Rate 0.08%
2021-01-06 12:56:08,614: INFO: Strategy IntradayMomentum: Executing the initialize lifecycle method
2021-01-06 12:56:08,614: INFO: Strategy IntradayMomentum: Executing the before_market_opens lifecycle method
2021-01-06 12:56:08,614: INFO: Current backtesting datetime 2018-01-02 09:30:00
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Executing the before_starting_trading lifecycle method
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Executing the on_trading_iteration lifecycle method
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Porfolio value of 40000
2021-01-06 12:56:08,615: ERROR: time_unit datetime.timedelta(seconds=60) did not match
2021-01-06 12:56:08,619: ERROR: Traceback (most recent call last):
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 529, in run
    self._run_trading_session()
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 488, in _run_trading_session
    self.on_trading_iteration()
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/tools/decorators.py", line 64, in func_output
    frame, result = call_function_get_frame(func_input, *args, **kwargs)
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/tools/decorators.py", line 24, in call_function_get_frame
    result = func(*args, **kwargs)
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/examples/intraday_momentum.py", line 22, in on_trading_iteration
    momentums = self.get_assets_momentums()
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/examples/intraday_momentum.py", line 54, in get_assets_momentums
    bars_set = self.get_symbol_bars(
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 333, in get_symbol_bars
    return self.data_source.get_symbol_bars(
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/data_source.py", line 34, in get_symbol_bars
    response = self._pull_source_symbol_bars(
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/backtesting/yahoo_backtesting.py", line 21, in _pull_source_symbol_bars
    result = YahooData._pull_source_symbol_bars(
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/yahoo.py", line 37, in _pull_source_symbol_bars
    self._parse_source_time_unit(time_unit, reverse=True)
  File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/yahoo.py", line 34, in _parse_source_time_unit
    raise ValueError("time_unit %r did not match" % time_unit)
ValueError: time_unit datetime.timedelta(seconds=60) did not match

2021-01-06 12:56:08,620: WARNING: Strategy IntradayMomentum: sell all

Remove strategy name.

Strategy name is not relevant or used and should be removed. Consider making it optional.

Release at same time as budget as users will need to be notified. jk

Issues with building from source

Commands used:

python3 setup.py build
sudo python3 setup.py install

System: Ubuntu 22.04.2 LTS

Initial error encountered:

aiohttp/_http_parser.c: In function ‘__pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser’:
aiohttp/_http_parser.c:16227:5: error: lvalue required as increment operand
16227 |     ++Py_REFCNT(o);
      |     ^~
aiohttp/_http_parser.c:16229:5: error: lvalue required as decrement operand
16229 |     --Py_REFCNT(o);
      |     ^~
...
error: Setup script exited with error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1

Further context:

Searching for aiohttp>=3.8
Reading https://pypi.org/simple/aiohttp/
Downloading https://files.pythonhosted.org/packages/f0/f2/703dba52c7620199ea0ec8ea9a4a2f06203b4893b94f60240c2c10225043/aiohttp-4.0.0a1.tar.gz#sha256=b5036133c1ba77ed5a70208d2a021a90b76fdf8bf523ae33dae46d4f4380d86f
Best match: aiohttp 4.0.0a1
Processing aiohttp-4.0.0a1.tar.gz
Writing /tmp/easy_install-ldm_vha_/aiohttp-4.0.0a1/setup.cfg
Running aiohttp-4.0.0a1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-ldm_vha_/aiohttp-4.0.0a1/egg-dist-tmp-1ekddkau

It seems like the requires.txt of ccxt-3.0.61 introduces the aiohttp>=3.8 dependency. This is interpreted to identify 4.0.0a1 as the latest version, unfortunately it is not considered a stable version (aio-libs/aiohttp#6898). One workaround I've been able to find is to force the correct version number in setup.py:

setuptools.setup(
    name="lumibot",
    version="2.7.5",
  .....
    packages=setuptools.find_packages(),
    install_requires=[
        "aiohttp==3.8.1",
        "polygon==1.1.0",
        "alpaca_trade_api==2.3.0",

Part of me feels this could be considered a setuptools shortcoming, as alpaca_trade_api tries to lock the version of aiohttp to 3.8.1. In fact, if I install aiohttp version 3.8.2 which succeeds - I get an error later down the line stating:

Installed /usr/local/lib/python3.10/dist-packages/aiohttp-3.8.2-py3.10-linux-x86_64.egg
error: aiohttp 3.8.2 is installed but aiohttp==3.8.1 is required by {'alpaca-trade-api'}

Yesterday's dividends unavailable in Interactive Brokers API

This has been discussed in Discord, but logging the issue here as well.

Lumibot has a method get_yesterday_dividend and get_yesterday_dividends which returns the yesterday dividend.

Interactive Brokers does not provide this particular level of information. According to IB docs, IB provides the following:

IB Dividends

This tick type provides four different comma-separated elements:

    The sum of dividends for the past 12 months (0.83 in the example below).
    The sum of dividends for the next 12 months (0.92 from the example below).
    The next dividend date (20130219 in the example below).
    The next single dividend amount (0.23 from the example below).

Example: 0.83,0.92,20130219,0.23

To receive dividend information it is sometimes necessary to direct-route rather than smart-route market data requests.

For the time being no dividend information will be returned in lumibot.

Handle gracefully when asset does not exists

User can make a a symbol typo while requesting data. If the given symbol does not match any existing share in the stock exchange and the data source return no data, lumibot must handle this gracefully.

Screener strategy not working in live mode

Here is the result of running the strategy:

(base) Roberts-MBP:alpaca-bots robertgrzesik$ python main.py screener -l
2021-01-05 14:15:19,727: INFO: Strategy Screener: Executing the initialize lifecycle method
2021-01-05 14:15:20,045: INFO: Strategy Screener: Executing the before_starting_trading lifecycle method
2021-01-05 14:15:20,046: WARNING: Strategy Screener: sell all
2021-01-05 14:15:20,083: INFO: Strategy Screener: Executing the on_trading_iteration lifecycle method
2021-01-05 14:15:20,084: INFO: Strategy Screener: Porfolio value of 40000
2021-01-05 14:15:20,084: INFO: Requesting asset bars from alpaca API
2021-01-05 14:15:24,496: INFO: Note: NumExpr detected 12 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2021-01-05 14:15:24,497: INFO: NumExpr defaulting to 8 threads.
2021-01-05 14:16:17,100: INFO: Selecting best positions
2021-01-05 14:16:17,105: ERROR: index -1 is out of bounds for axis 0 with size 0
2021-01-05 14:16:17,110: ERROR: Traceback (most recent call last):
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 523, in run
    self._run_trading_session()
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 482, in _run_trading_session
    self.on_trading_iteration()
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 64, in func_output
    frame, result = call_function_get_frame(func_input, *args, **kwargs)
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 24, in call_function_get_frame
    result = func(*args, **kwargs)
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 36, in on_trading_iteration
    self.buy_winning_stocks(
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 60, in buy_winning_stocks
    new_positions = self.select_assets(data, min_increase_target)
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 82, in select_assets
    momentum = bars.get_momentum()
  File "/Users/robertgrzesik/Development/alpaca-bots/entities/bars.py", line 25, in get_momentum
    momentum = self.df["close"].pct_change(n_rows - 1)[-1]
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/series.py", line 879, in __getitem__
    return self._values[key]
IndexError: index -1 is out of bounds for axis 0 with size 0

2021-01-05 14:16:17,110: WARNING: Strategy Screener: sell all
The end

Futures example not working

The futures.py example in example_strategies\futures.py does not work: the code picks up the default asset "USD" rather than one of the futures passed in lumibot.entities.Data(... Asset=,...)

Interactive Brokers reqHistoricalData doesn't return data when using TimeShift/endDateTime

Timeshift not working for the moment. When calling reqHistoricalData from IB using timeshift or endDateTime no data is returned. This is true even when entering the datetime manually as a string. When using "" empty string the TWS server current time is always fetched and data is returned.

IB docs on the issues can be found here. # https://interactivebrokers.github.io/tws-api/historical_bars.html
IB is looking for a str in the prescribed format of .strftime("%Y%m%d %H:%M:%S") or manually using "20210405 11:00:00"

The result is not an error but just IB not returning data.

Bug in the function "is_market_open()" and possibly other functions

Hi, I'm a new Lumibot user in Singapore. I found that I can't submit market order after midnight (12:00 am) local time, and in my Spyder console, it shows: Sleeping until the market opens.

After some checking, I found that in the file broker.py, there is a bug in the function is_market_open().
In this function, this line:
open_time = self.utc_to_local(self.market_hours(close=False))
gives the open time. It works as intended before midnight Singapore time say on Friday. However, when I run this line after 12 am Singapore time, it actually shows the open time of next Monday. Although the market is still open because it is at noon New York time, the variable current_time is earlier than the open time of next Monday, so this line:
return (current_time >= open_time) and (close_time >= current_time)
will return "false".

Here are some lines I run in my console and their outputs for your reference:

alpaca.is_market_open()
Out[2]: False

alpaca.api.get_clock()
Out[3]: 
Clock({   'is_open': True,
    'next_close': '2023-05-05T16:00:00-04:00',
    'next_open': '2023-05-08T09:30:00-04:00',
    'timestamp': '2023-05-05T15:18:19.101183152-04:00'})
alpaca.utc_to_local(alpaca.market_hours(close=False))
Out[8]: Timestamp('2023-05-08 21:30:00+0800', tz='tzlocal()')

alpaca.utc_to_local(alpaca.market_hours(close=True))
Out[9]: Timestamp('2023-05-09 04:00:00+0800', tz='tzlocal()')

datetime.now().astimezone(tz=tz.tzlocal())
Out[10]: datetime.datetime(2023, 5, 6, 3, 33, 53, 871817, tzinfo=tzlocal())

open_time=alpaca.utc_to_local(alpaca.market_hours(close=False))

close_time=alpaca.utc_to_local(alpaca.market_hours(close=True))

current_time = datetime.now().astimezone(tz=tz.tzlocal())

current_time >= open_time
Out[14]: False

close_time >= current_time
Out[15]: True

As I mentioned earlier, when I try to submit a market order after midnight, it shows: Sleeping until the market opens. This may mean that there is a similar issue in the function trader.run_all() or other functions it calls.

Hopefully this bug can be fixed soon.
Thanks!
Shengchuang

self.cash Is None

When using the self.cash property while trades have not yet been executed, it will return a small value such as 15$ during live trading. If run from a script such as main.py with a custom historical_data_function (OHLCV), it could also return None. It is mainly caused by specifying a budget, 10,000 in this case.

This leads to improper calculation of trades along with logging issues. Example code has been provided:

from config import ALPACA_CONFIG
from lumibot.brokers import Alpaca
from lumibot.strategies import Strategy
from lumibot.traders import Trader


class BuyHold(Strategy):

    def initialize(self):
        self.sleeptime = "1D"

    def on_trading_iteration(self):
        self.log_message(f"Cash Is: {self.cash}$")
        if self.first_iteration:
            symbol = "GOOG"
            price = self.get_last_price(symbol)
            quantity = self.cash // price
            order = self.create_order(symbol, quantity, "buy")
            self.submit_order(order)

if __name__ == "__main__":
    broker = Alpaca(ALPACA_CONFIG)
    strategy = BuyHold(broker=broker, budget=10000)
    trader = Trader()
    trader.add_strategy(strategy)
    trader.run_all()

Circular import

Neil Murphy recommended that I look at lumibot and so I installed and tried to run the buy_and_hold.py example. I'm doing this on an M1 Mac where conda is pointed to all osx-arm64 libraries. Running pip install lumibot fails because many libraries aren't able to be built likely because of M1 issues. I've therefore created a mod_requirements.txt file where I removed libaries that conda doesn't have to create this file:

# Brokers and Datasources dependecies

# Datascience dependencies
pandas==1.2.4

# Flask ecosystem dependencies
Flask-socketio===4.3.2
flask-sqlalchemy==2.5.1
flask-marshmallow==0.14.0
marshmallow-sqlalchemy==0.24.3
flask-security==3.0.0
email_validator==1.1.2 # flask_security dependency (not mentionned)
bcrypt==3.2.0 # flask_security dependency (not mentionned)

# Testing dependencies
pytest==6.2.3

# Linting dependencies
black==20.8b1
isort==5.8.0

I then installed with the following:

conda create -n lumibot
conda activate lumibot
conda install --file mod_requirements.txt
conda install matplotlib
pip install lumibot
python -c "import lumibot"

That allows pip to install the remaining libraries and the import works fine. But when I try any of the examples in lumibot with other imports like this they fail:

python -c "from lumibot.strategies.strategy import Strategy"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/strategies/__init__.py", line 1, in <module>
    from .strategy import Strategy
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/strategies/strategy.py", line 3, in <module>
    from lumibot.entities import Asset, Order
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/__init__.py", line 3, in <module>
    from .bars import Bars
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/bars.py", line 6, in <module>
    from lumibot.data_sources.exceptions import NoDataFound
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/data_sources/__init__.py", line 1, in <module>
    from .alpaca_data import AlpacaData
  File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/data_sources/alpaca_data.py", line 8, in <module>
    from lumibot.entities import Bars
ImportError: cannot import name 'Bars' from partially initialized module 'lumibot.entities' (most likely due to a circular import) (/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/__init__.py)

It seems some sort of circular import of from lumibot.entities import Asset, Order eventually leads to from lumibot.entities import Bars which is not possible. I get similar errors with other example files.

The installed version of lumibot is version 1.1.7. Any ideas what could be causing this? The libraries seems to be installed fine but it doesn't like referencing the same module twice even though it's for a different class.

bug in pandas_market_calendars 4.0

Hi all,

Attempting to test out lumibot but can't get the getting started backtest to work. With a fresh venv of python 3.9.13 and after a pip install lumibot I run the sample code in the getting started guide. I get this error:

ValueError: cannot reindex on an axis with duplicate labels

On line 42 of helpers.py:

days = nyse.schedule(start_date="1950-01-01", end_date=today)

It seems like this is a known issue of pandas_market_calendars 4.0 and is fixed in 4.0.1. However, 4.0.1 doesn't exist on pypi and 4.0 seems to be a hardcoded dependency.

rsheftel/pandas_market_calendars#215

Can anyone help me get lumibot installed? Wouldn't this issue impact fresh deployments of pre-existing users?

Thanks,
Brett

Intraday momentum example never changes values

I ran the intraday momentum example and let it run for a bit. The momentum percentages sometimes do not change. Actually for most of them they do not change. How can a stock have the exact same 0.09% momentum each minute? Even if a stock does not trade and does not change value then the new momentum should be 0%. Of the 8 stocks I put in the list, maybe 1 changes every minute? Shouldn't they all change? I have had one have a momentum of 6.27% every minute for the past 6 mins. That does not seem to make sense.

Stopping execution with CTRL+C does not stop the execution effectively

This is what happens after I press CTRL+C:

^C2021-01-05 14:12:30,767: INFO: Strategy IntradayMomentum: Executing the on_abrupt_closing lifecycle method
2021-01-05 14:12:30,767: WARNING: Strategy IntradayMomentum: sell all
2021-01-05 14:12:30,826: INFO: market order of | 218 GLD sell | with status accepted was sent to broker 
Traceback (most recent call last):
  File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 87, in run_all
    for task in as_completed(tasks):
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py", line 244, in as_completed
    waiter.event.wait(wait_timeout)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 558, in wait
    signaled = self._cond.wait(timeout)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 302, in wait
    waiter.acquire()
  File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 58, in _abrupt_closing
    strategy.on_abrupt_closing()
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 83, in output_func
    action()
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 187, in _dump_stats
    cagr_value = cagr(df_)
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/indicators.py", line 33, in cagr
    CAGR = (total_ret) ** (1 / period_years) - 1
ZeroDivisionError: float division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 79, in <module>
    trader.run_all()
  File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 88, in run_all
    results.append(task.result())
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py", line 636, in __exit__
    self.shutdown(wait=True)
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py", line 236, in shutdown
    t.join()
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 1011, in join
    self._wait_for_tstate_lock()
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 1027, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
  File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 58, in _abrupt_closing
    strategy.on_abrupt_closing()
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 83, in output_func
    action()
  File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 185, in _dump_stats
    df_ = df_day_deduplicate(self.stats_df)
  File "/Users/robertgrzesik/Development/alpaca-bots/tools/helpers.py", line 32, in df_day_deduplicate
    if position + 1 == n_rows:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
2021-01-05 14:12:30,866: INFO: New market order of | 218 GLD sell | with status accepted was submited.
2021-01-05 14:12:30,932: INFO: New transaction: sell 151 of GLD at 182.98$ per share
2021-01-05 14:12:30,932: INFO: market order of | 218 GLD sell | with status new was partially filled
^C2021-01-05 14:12:30,966: INFO: Strategy IntradayMomentum: Executing the on_abrupt_closing lifecycle method
2021-01-05 14:12:30,967: WARNING: Strategy IntradayMomentum: sell all
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/Users/robertgrzesik/Development/alpaca-bots/brokers/broker.py", line 332, in cancel_orders
    tasks.append(executor.submit(self.cancel_order, order))
  File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py", line 181, in submit
    raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
(base) Roberts-MBP:alpaca-bots robertgrzesik$ 

Polygon.io Backtesting example is failing

Hello,

from datetime import datetime
from lumibot.backtesting import PolygonDataBacktesting
from lumibot.strategies import Strategy

class MyStrategy(Strategy):
    parameters = {
        "symbol": "AAPL",
    }

    def initialize(self):
        self.sleeptime = "1D"

    def on_trading_iteration(self):
        if self.first_iteration:
            symbol = self.parameters["symbol"]
            price = self.get_last_price(symbol)
            qty = self.portfolio_value / price
            order = self.create_order(symbol, quantity=qty, side="buy")
            self.submit_order(order)

if __name__ == "__main__":
    backtesting_start = datetime(2023, 1, 1)
    backtesting_end = datetime(2023, 5, 1)

    MyStrategy.backtest(
        PolygonDataBacktesting,
        backtesting_start,
        backtesting_end,
        polygon_api_key="YOUR_POLYGON_API_KEY",
        polygon_has_paid_subscription=False,
    )

raises

>python bot.py
Starting backtest for MyStrategy...
ERROR:root:Error getting the risk free rate: 401 Client Error: Unauthorized for url: https://query2.finance.yahoo.com/v10/finance/quoteSummary/%5EIRX?modules=summaryProfile%2CfinancialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&ssl=true
INFO:backtest_stats:Starting backtest...
Progress |█--------------------------------------------------------|   2.00%  [Elapsed: 0:00:03 ETA: 0:02:33]
Getting pricing data for AAPL from Polygon...
2023-07-14 16:37:06,634: root: ERROR: unsupported operand type(s) for /: 'float' and 'NoneType'
2023-07-14 16:37:06,637: root: ERROR: Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 570, in run
    self._run_trading_session()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 538, in _run_trading_session
    self._on_trading_iteration()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
    result = func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 285, in func_output
    result = func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 69, in func_output
    return func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 339, in _on_trading_iteration
    on_trading_iteration()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\decorators.py", line 62, in func_output
    frame, result = call_function_get_frame(func_input, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\decorators.py", line 30, in call_function_get_frame
    result = func(*args, **kwargs)
  File "C:\Users\w4c\trading\lumibot\bot.py", line 17, in on_trading_iteration
    qty = self.portfolio_value / price
TypeError: unsupported operand type(s) for /: 'float' and 'NoneType'

after changing API key I run into an other problem...

>python bot.py
Starting backtest for MyStrategy...
ERROR:root:Error getting the risk free rate: 401 Client Error: Unauthorized for url: https://query2.finance.yahoo.com/v10/finance/quoteSummary/%5EIRX?modules=summaryProfile%2CfinancialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&ssl=true
INFO:backtest_stats:Starting backtest...
Progress |█--------------------------------------------------------|   2.00%  [Elapsed: 0:00:03 ETA: 0:02:27]
Getting pricing data for AAPL from Polygon...

Sleeping 60 seconds getting pricing data for AAPL from Polygon because we don't have a paid subscription and we don't want to hit the rate limit. If you want to avoid this, you can get a paid subscription at https://polygon.io/pricing and set `polygon_has_paid_subscription=True` when starting the backtest.

Progress |█████████████████████████████████████████████████████████| 100.00%  [Elapsed: 0:01:08 ETA: 0:00:00]2023-07-14 16:40:00,490: root: INFO: MyStrategy : --- MyStrategy Strategy Performance  ---
2023-07-14 16:40:00,509: root: INFO: MyStrategy : Total Return: 30.47%
2023-07-14 16:40:00,509: root: INFO: MyStrategy : CAGR 132.76%
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Volatility 23.27%
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Sharpe 5.71
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Max Drawdown 6.43% on 2023-03-02
2023-07-14 16:40:00,511: root: INFO: MyStrategy : RoMaD 2,065.44%
2023-07-14 16:40:00,511: root: INFO: MyStrategy : --- SPY Benchmark Performance ---

Getting pricing data for SPY from Polygon...

Sleeping 60 seconds getting pricing data for SPY from Polygon because we don't have a paid subscription and we don't want to hit the rate limit. If you want to avoid this, you can get a paid subscription at https://polygon.io/pricing and set `polygon_has_paid_subscription=True` when starting the backtest.

2023-07-14 16:41:00,900: root: ERROR: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
2023-07-14 16:41:00,905: root: ERROR: Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
    res = data.get_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
    raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 587, in run
    self._on_strategy_end()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
    result = func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 360, in _on_strategy_end
    self.strategy._dump_stats()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
    bars = self.data_source.get_historical_prices_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
    response = super()._pull_source_symbol_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
    raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.

2023-07-14 16:41:00,907: root: INFO: MyStrategy : Executing the on_bot_crash event method
2023-07-14 16:41:00,916: root: INFO: MyStrategy : --- MyStrategy Strategy Performance  ---
2023-07-14 16:41:00,932: root: INFO: MyStrategy : Total Return: 30.47%
2023-07-14 16:41:00,932: root: INFO: MyStrategy : CAGR 132.76%
2023-07-14 16:41:00,932: root: INFO: MyStrategy : Volatility 23.27%
2023-07-14 16:41:00,933: root: INFO: MyStrategy : Sharpe 5.71
2023-07-14 16:41:00,933: root: INFO: MyStrategy : Max Drawdown 6.43% on 2023-03-02
2023-07-14 16:41:00,933: root: INFO: MyStrategy : RoMaD 2,065.44%
2023-07-14 16:41:00,934: root: INFO: MyStrategy : --- SPY Benchmark Performance ---
Exception in thread MyStrategy:
Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
    res = data.get_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
    raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 587, in run
    self._on_strategy_end()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
    result = func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 360, in _on_strategy_end
    self.strategy._dump_stats()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
    bars = self.data_source.get_historical_prices_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
    response = super()._pull_source_symbol_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
    raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
    res = data.get_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
    raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\tools\Anaconda3\lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 591, in run
    self._on_bot_crash(e)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 273, in func_output
    result = func_input(self, *args, **kwargs)
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 371, in _on_bot_crash
    self.strategy._dump_stats()
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
    bars = self.data_source.get_historical_prices_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
    response = super()._pull_source_symbol_bars_between_dates(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
    raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
2023-07-14 16:41:00,959: backtest_stats: INFO: Backtest took 0:02:08.247696 for a speed of 0.000
2023-07-14 16:41:00,962: root: WARNING: Cannot plot returns because the benchmark returns are missing
Creating indicators plot...
Creating tearsheet...
Traceback (most recent call last):
  File "C:\Users\w4c\trading\lumibot\bot.py", line 25, in <module>
    MyStrategy.backtest(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 1049, in backtest
    strategy.tearsheet(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 695, in tearsheet
    create_tearsheet(
  File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\indicators.py", line 642, in create_tearsheet
    _df2 = df2.copy()
AttributeError: 'NoneType' object has no attribute 'copy'

Kind regards

Make budget parameter optional.

The budget parameter is no longer used in live trading since the cash amounts and securities values in the accounts are being used.

Need to remove budget as a positional argument in Strategy, make keyword arg.

Notify users.

Add limit and stop orders to backtesting

it would look something like this:
12pm:
stock is trading at $4
put in limit sell order at $4.50
12:01pm:
stock trading at $4.20
do nothing
12:02pm:
stock trading at $4.60
assume we bought at $4.50

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.