I am new to QuantConnect and have been using AI to assist me in making the algorithm I want. I want my program to filter stocks that are between 2-20 dollars, have a small market cap, and have increased by at least ten percent in the past hour. I only want my program to invest in one of these stocks if the MACD is bullish and it has a relative volume of 5 over the past fifty days. Then the program will sell when the stock grows by 5% or stops out at 98% of the original investment.
I'm not sure what is wrong with the code, but it never placed any orders. I'll include the code below and if you have any suggestions that would be greatly appreciated!
from AlgorithmImports import *
class OpeningGapStrategy(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 1, 1) # Set Start Date
self.SetEndDate(2024, 1, 1) # Set End Date
self.SetCash(1000) # Set Strategy Cash
self.stocks = [] # List to hold our stocks
self.stop_loss_percent = 0.98
self.take_profit_percent = 1.05
# Define the trading hours
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(9, 30), self.ScanForStocks)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(10, 30), self.CheckAndBuy) # Check one hour after market open
def ScanForStocks(self):
# Initialize the universe with filtering criteria
self.AddUniverse(self.UniverseFilter)
self.Debug("Scanning for stocks")
def UniverseFilter(self, coarse):
# Filter for small cap stocks with price between $2 and $20
filtered_symbols = [x.Symbol for x in coarse
if x.MarketCap < 2e9 and 2 < x.Price < 20]
self.Debug(f"Filtered Symbols: {filtered_symbols}")
return filtered_symbols
def CheckAndBuy(self):
if not self.ActiveSecurities:
self.Debug("No active securities.")
return
for symbol in self.ActiveSecurities.Keys:
if symbol in self.Portfolio and self.Portfolio[symbol].Invested:
continue
# Ensure the security is initialized
security = self.Securities[symbol]
if not security.HasData:
self.Debug(f"No data for {symbol}")
continue
# Fetch historical data for the first hour
try:
history = self.History(symbol, 90, Resolution.Minute) # Request more data to ensure we capture the first hour
if history.empty or len(history) < 60: # Ensure we have enough data for the first hour
self.Debug(f"Insufficient historical data for {symbol}. Data Length: {len(history)}")
continue
# Calculate growth percentage
open_price = history.iloc[0].close # Price at market open
one_hour_later_price = history.iloc[60].close # Price one hour later (adjust index if necessary)
growth_percentage = (one_hour_later_price - open_price) / open_price
# Log growth percentage
self.Debug(f"{symbol} - Open Price: {open_price}, One Hour Later Price: {one_hour_later_price}, Growth: {growth_percentage:.2%}")
# Check trading condition
if growth_percentage >= 0.10: # 10% growth
# Place order to buy the stock
quantity = self.Portfolio.Cash / self.Securities[symbol].Price # Determine quantity based on available cash
self.SetHoldings(symbol, 1.0) # Allocate 100% of the portfolio to this stock
self.Debug(f"Placed order for {symbol}")
# Set stop loss and take profit orders
stop_loss_price = one_hour_later_price * self.stop_loss_percent
take_profit_price = one_hour_later_price * self.take_profit_percent
self.Debug(f"Set Stop Loss at {stop_loss_price} and Take Profit at {take_profit_price}")
# Place stop-loss order
self.StopMarketOrder(symbol, quantity, stop_loss_price)
# Place take-profit order
self.LimitOrder(symbol, quantity, take_profit_price)
except Exception as e:
self.Debug(f"Error fetching data for {symbol}: {str(e)}")
def OnData(self, slice):
if not self.Portfolio.Invested:
self.Debug("No open positions")
return
for symbol in list(self.Portfolio.Keys):
if self.Portfolio[symbol].Invested:
price = self.Portfolio[symbol].Price
if price <= self.stop_loss_price or price >= self.take_profit_price:
self.Liquidate(symbol)
self.Debug(f"Liquidated {symbol} at {price}")
# Reset stop-loss and take-profit prices
self.stop_loss_price = None
self.take_profit_price = None
Louis Szeto
Hi Benny
The universe subscription should be only handled in the initialize method and it will run daily, but not in a scheduled function.
As per the MACD filtering, I recommend you check out Example 2: Take 10 stocks above their 200-Day EMA and have more than $1B daily trading volume as a similar example in the fundamental universe docs examples.
Best
Louis
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Benny Bones
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!