QuantConnect Algorithm Issues - Complete Questions for Support Bot

Overview

I'm developing a stock scanner algorithm that monitors news and volume spikes. I'm encountering several API usage issues and need clarification on the correct implementation patterns.

Complete Code Sections with Issues

ISSUE 1: Fundamental Data Access in Universe Selection

Current Code (main.py, lines 811-847):

def _get_shares_outstanding(self, fine_fundamental):
    """Extract shares outstanding with multiple attempts"""
    try:
        # Attempt 1: CompanyReference.SharesOutstanding
        if hasattr(fine_fundamental, 'CompanyReference') and hasattr(fine_fundamental.CompanyReference, 'SharesOutstanding'):
            shares = fine_fundamental.CompanyReference.SharesOutstanding
            if shares and shares > 0:
                return shares
        
        # Attempt 2: EarningReports.BasicAverageShares
        if hasattr(fine_fundamental, 'EarningReports') and hasattr(fine_fundamental.EarningReports, 'BasicAverageShares'):
            shares = fine_fundamental.EarningReports.BasicAverageShares.ThreeMonths
            if shares and shares > 0:
                return shares
        
        # Attempt 3: FinancialStatements.SharesOutstanding
        if hasattr(fine_fundamental, 'FinancialStatements') and hasattr(fine_fundamental.FinancialStatements, 'SharesOutstanding'):
            shares = fine_fundamental.FinancialStatements.SharesOutstanding.ThreeMonths
            if shares and shares > 0:
                return shares
        
        return None
    except Exception as e:
        return None

def fine_selection(self, fine):
    """Fine Universe Selection"""
    try:
        fine_list = list(fine)
        qualified = []
        
        for x in fine_list:
            try:
                # Which is correct?
                # Option 1: PascalCase
                if hasattr(x, 'CompanyReference'):
                    shares = x.CompanyReference.SharesOutstanding
                
                # Option 2: snake_case  
                if hasattr(x, 'company_reference'):
                    shares = x.company_reference.shares_outstanding
                
                # Option 3: Direct access
                shares_outstanding = x.shares_outstanding
                market_cap = x.market_cap
                
                # Filter criteria
                if (shares_outstanding and 
                    shares_outstanding <= 30_000_000 and
                    5_000_000 <= market_cap <= 100_000_000):
                    qualified.append(x)
                    
            except Exception as e:
                continue
        
        return [x.symbol for x in qualified[:900]]
        
    except Exception as e:
        self.error(f"Error: {e}")
        return []

Question 1: What is the correct attribute naming convention for accessing fundamental data in Python? Is it PascalCase (CompanyReference.SharesOutstanding) or snake_case (company_reference.shares_outstanding)? Please provide the complete hierarchy for accessing:

  • Shares outstanding (including float shares)
  • Market capitalization
  • Earning reports data
  • Company reference data

ISSUE 2: ATR Indicator Configuration and Access

Current Code (symbol_data.py, lines 40-45 and 285-310):

from QuantConnect.Indicators import MovingAverageType

class SymbolData:
    def __init__(self, algorithm, symbol):
        self.algo = algorithm
        self.symbol = symbol
        self.price = 0.0
        
        # ATR initialization - which is correct?
        # Option 1: lowercase with DAILY resolution
        self.atr = algorithm.atr(symbol, 21, MovingAverageType.SIMPLE, Resolution.DAILY)
        
        # Option 2: uppercase with MINUTE resolution
        self.atr = algorithm.ATR(symbol, 21, MovingAverageType.Simple, Resolution.Minute)
        
        self.atr_ready = False
    
    def update_price(self, price):
        """Update price and check ATR readiness"""
        self.price = price
        
        # How to check if ATR is ready and get its value?
        # Option 1: lowercase
        if hasattr(self, 'atr') and self.atr.is_ready:
            self.atr_ready = True
            atr_value = self.atr.current.value
            
        # Option 2: PascalCase
        if hasattr(self, 'atr') and self.atr.IsReady:
            self.atr_ready = True
            atr_value = self.atr.Current.Value
    
    def get_adaptive_min_move(self):
        """Calculate adaptive minimum move based on ATR"""
        if not self.atr_ready or self.price == 0:
            return 1.0  # default
        
        # Which is correct for accessing ATR value?
        # Option 1:
        atr_percent = (self.atr.current.value / self.price) * 100
        
        # Option 2:
        atr_percent = (self.atr.Current.Value / self.price) * 100
        
        return atr_percent * 0.5

Question 2:

  1. When securities are added with Resolution.MINUTE, can I create ATR with Resolution.DAILY?
  2. Is the method name algorithm.atr() or algorithm.ATR()?
  3. How do I access ATR properties: atr.current.value or atr.Current.Value?
  4. Is it atr.is_ready or atr.IsReady?
  5. What happens if I mix resolutions between data subscription and indicators?

ISSUE 3: Symbol Data Properties and Bar Data Access

Current Code (main.py, lines 1050-1100):

def on_data(self, slice_data):
    """Process incoming data"""
    try:
        # Update SPY price - which property?
        if self.spy_symbol in slice_data.bars:
            # Option 1: lowercase
            self.spy_current_price = slice_data.bars[self.spy_symbol].close
            
            # Option 2: PascalCase
            self.spy_current_price = slice_data.bars[self.spy_symbol].Close
        
        # Process symbols
        for symbol, symbol_data in self.symbol_data_dict.items():
            if symbol not in slice_data.bars:
                continue
            
            bar = slice_data.bars[symbol]
            
            # Which is correct?
            # Option 1: lowercase
            symbol_data.update_price(bar.close)
            symbol_data.update_volume(bar.volume)
            
            # Option 2: PascalCase
            symbol_data.update_price(bar.Close)
            symbol_data.update_volume(bar.Volume)

def _check_reaction_alert(self, symbol, symbol_data):
    """Check reaction with incorrect property access"""
    # ERROR: Using current_price which doesn't exist
    self.log(f"Symbol: {symbol.value} | Price: ${symbol_data.current_price:.2f}")
    
    # Should it be:
    self.log(f"Symbol: {symbol.value} | Price: ${symbol_data.price:.2f}")
    
    # Calculate dollar volume
    dollar_volume = symbol_data.current_price * symbol_data.volume  # ERROR?
    # Or should it be:
    dollar_volume = symbol_data.price * symbol_data.volume

Question 3:

  1. What are the correct property names for bar data: bar.close/bar.volume or bar.Close/bar.Volume?
  2. Is there a current_price property in SymbolData or should I use my custom price property?
  3. What's the Python API naming convention - snake_case or PascalCase?

ISSUE 4: BenzingaNews Data and Timezone Handling

Current Code (news_analyzer.py, lines 85-120):

import pytz
from AlgorithmImports import *

class NewsAnalyzer:
    def process_news(self, slice_data, symbol_data_dict):
        """Process incoming news with timezone issues"""
        news_dict = slice_data.get(BenzingaNews)
        if not news_dict:
            return
        
        for symbol, news_item in news_dict.items():
            try:
                # Filter old news - timezone comparison issue
                if hasattr(news_item, 'time') and news_item.time:
                    # Getting timezone errors here
                    algo_time = self.algo.utc_time
                    news_time = news_item.time
                    
                    # Attempt 1: Direct comparison (causes timezone error)
                    news_age = (algo_time - news_time).total_seconds()
                    
                    # Attempt 2: Make both timezone-aware
                    if algo_time.tzinfo is None and news_time.tzinfo is not None:
                        algo_time = pytz.utc.localize(algo_time)
                    elif algo_time.tzinfo is not None and news_time.tzinfo is None:
                        news_time = pytz.utc.localize(news_time)
                    
                    news_age = (algo_time - news_time).total_seconds()
                    if news_age > 120:  # Older than 2 minutes
                        continue
                
                # Access news properties - which exist?
                importance = news_item.importance  # Does this exist?
                headline = news_item.headline  # or news_item.title?
                url = news_item.url  # or news_item.link?
                symbols = news_item.symbols  # list of affected symbols?
                
            except Exception as e:
                self.algo.error(f"Error: {e}")

Question 4:

  1. What properties are available on BenzingaNews items?
  2. Is news_item.time timezone-aware or naive?
  3. How should I properly compare self.utc_time with news_item.time?
  4. What's the correct way to filter old news items?
  5. Do I need to handle timezone conversion or does QuantConnect handle it?

ISSUE 5: Universe Selection with ObjectStore

Current Code (main.py, lines 220-280):

def initialize(self):
    """Initialize with ObjectStore and Universe Selection"""
    try:
        self.set_start_date(2024, 1, 1)
        self.set_cash(100000)
        
        # Load from ObjectStore
        if self.object_store.contains_key("filtered_universe_900"):
            symbols_str = self.object_store.read("filtered_universe_900")
            self.target_symbols = symbols_str.split(',')
            
            # Manual universe addition
            for ticker in self.target_symbols:
                # Will this conflict with Universe Selection?
                symbol = self.add_equity(ticker, Resolution.MINUTE).symbol
                self.symbol_data_dict[symbol] = SymbolData(self, symbol)
                self.add_data(BenzingaNews, symbol)
            
            self.bootstrap_completed = True
        
        # Also register Universe Selection
        self.universe_settings.resolution = Resolution.DAILY
        self.add_universe(self.coarse_selection, self.fine_selection)
        
    except Exception as e:
        self.error(f"Error: {e}")

def on_securities_changed(self, changes):
    """Handle universe changes - potential duplicates?"""
    for added in changes.added_securities:
        symbol = added.symbol
        
        # Check for duplicates?
        if symbol in self.symbol_data_dict:
            continue  # Is this sufficient?
        
        self.symbol_data_dict[symbol] = SymbolData(self, symbol)
        self.add_data(BenzingaNews, symbol)

Question 5:

  1. Will manually adding securities with add_equity() conflict with Universe Selection?
  2. Can the same symbol be added twice (manually and via Universe)?
  3. What's the proper way to check if a symbol already exists in the universe?
  4. How can I skip Universe Selection when loading from ObjectStore?
  5. Is Universe.UNCHANGED the right way to skip selection?

ISSUE 6: Notification and Logging Methods

Current Code (telegram_notifier.py and main.py):

class TelegramNotifier:
    def _send_message(self, message):
        """Send Telegram notification"""
        try:
            # Which method is correct?
            # Option 1:
            success = self.algo.notify.telegram(chat_id, message, token)
            
            # Option 2:
            success = self.algo.Notify.Telegram(chat_id, message, token)
            
            # Option 3:
            success = self.algo.notify.Telegram(chat_id, message, token)
            
            return success
        except Exception as e:
            # How to log errors?
            self.algo.error(f"Error: {e}")  # Does error() exist?
            self.algo.log(f"Error: {e}")     # Or use log()?
            self.algo.debug(f"Error: {e}")   # Does debug() exist?

# In main.py
def initialize(self):
    # Which logging methods are available?
    self.log("Info message")        # Works?
    self.debug("Debug message")     # Works?
    self.error("Error message")     # Works?
    self.warning("Warning message") # Works?

Question 6:

  1. What's the correct method for Telegram notifications?
  2. What logging methods are available: log(), debug(), error(), warning()?
  3. Do these methods automatically include timestamps?
  4. Is there a log level setting to control output?

ISSUE 7: Missing Classes and Methods

Current Code references these potentially missing items:

# In symbol_data.py
from anomaly_detector import AnomalyDetector  # Custom class not found
from technical_indicators import TechnicalIndicators  # Custom class not found

class SymbolData:
    def __init__(self, algorithm, symbol):
        # These classes don't exist in provided code
        self.anomaly_detector = AnomalyDetector(algorithm, symbol, window_size=30)
        self.technical_indicators = TechnicalIndicators(algorithm, symbol)
    
    def reset_daily(self):  # This method is called but not defined
        """Reset daily data"""
        pass

# In main.py
def reset_daily_states(self):
    for symbol_data in self.symbol_data_dict.values():
        symbol_data.reset_daily()  # Calling undefined method

Question 7:

  1. Should I implement these missing classes or are there QuantConnect equivalents?
  2. For custom SymbolData class, what methods are required vs optional?
  3. Is there a built-in pattern for tracking per-symbol state?

Summary Questions for Complete Clarification

Question 8 - Best Practices:

  1. What's the recommended way to structure a complex algorithm with multiple components?
  2. Should I use separate files for each class or keep everything in main.py?
  3. What's the memory/performance impact of storing custom data for 900 symbols?
  4. Are there limits on ObjectStore size and access frequency?
  5. What's the proper way to handle algorithm warm-up with historical data?

Question 9 - Complete Working Example Request: Could you provide a minimal working example that demonstrates:

  • Proper Universe Selection with fundamental filters
  • Correct ATR indicator setup with minute data
  • BenzingaNews subscription and data access
  • Proper timezone handling
  • Telegram notification sending

Thank you for your help in resolving these issues!