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()
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.