# Detailed Question for QuantConnect Expert Bot

---

## Problem Summary:

I have a QuantConnect trading algorithm that uses **Universe Selection** to select stocks and monitor Benzinga news. The problem is that the system **is not adding any stocks** after running f∈ese≤ction(), even though it successfully processes 900 stocks in coarsese≤ction().

---

## Context:

### Old Version (Was Working):
- Added **49 stocks** immediately after ∈itialize()
- **Did NOT use** UniverseSe≤ction (no [CoarseSe≤ction] or [F∈eSe≤ction] logs appeared)
- Loaded stocks from a **hardcoded list** or **ObjectStore**
- Stocks were added directly without going through the Universe Selection pipeline

### Current Version (Not Working):
- Uses dynamic UniverseSe≤ction
- coarsese≤ction() works successfully and sends **900 stocks** to f∈ese≤ction()
- f∈ese≤ction() **rejects ALL stocks** and returns **0 stocks**
- Result: onsecuritieschan≥d() receives **0 added stocks**
- No news monitoring happens because no stocks are in the universe

---

## Logs Evidence:

### Successful Run (Old Version - Sept 30):
2025−09−3013:50:49Algorithm∈itialized≻esl–y.2025−09−3013:50:49Universechan≥s:SecurityChan≥s:Added:A,∀,∀L,∀OI,∀ON,∀P,∀RD,∀T,AC,ABBV,ABCB,ABCL,ABG,ABM,ABNB,ABR,ABSI,ABT,ABVE,ACA,ACAD,ACB...(49s→cks→tal)
✅ **49 stocks added immediately**
✅ **No CoarseSelection or FineSelection logs** (bypassed Universe Selection)

---

### Failed Run (Current Version - Oct 3):
2025−10−0300:41:18[Initialize]Se∈gupUniverseSe≤ction...2025−10−0300:41:18[Initialize]UniverseSe≤ctionregistered≻esl–y2025−10−0300:41:18[Initialize]ObjectS→reenab≤d−aempt∈gimmediateload∈g...2025−10−0300:41:18[ObjectS→re]Loaded585s→cks2025−10−0300:41:18[Initialize]Nosavedlist−willwaitforUniverseSe≤ction(00:00−00:30AM)2025−10−0300:41:18[OnSecuritiesChan≥d]Update#1|Added:1|Removed:02025−10−0300:41:18[OnSecuritiesChan≥d]Totalactives→cks:0

Then 5 hours later:
2025−10−0306:00:09[CoarseSe≤ction]Start∈gCoarseSe≤ction−Time:2025−10−0302:00:002025−10−0306:00:09[CoarseSe≤ction]Totalavailab≤s→cks:103342025−10−0306:00:09[CoarseSe≤ction]Afterpricefi<er:3119s→cks2025−10−0306:00:09[CoarseSe≤ction]Se≤cted900s→cksforF∈eSe≤ction2025−10−0306:00:09[F∈eSe≤ction]Start∈gF∈eSe≤ction−Time:2025−10−0302:00:002025−10−0306:00:09[F∈eSe≤ction]Received900s→cksomCoarseSe≤ction2025−10−0306:00:09[F∈eSe≤ction]AfterMarketCap+Sharesfi<er:0s→cks❌2025−10−0306:00:09[F∈eSe≤ction]Aftersort∈g:Se≤ctedbest0s→cks(LowFloat)2025−10−0306:00:09[F∈eSe≤ction]F∈eSe≤ctioncomp≤te−Send∈g0s→cks→onsecuritieschan≥d

❌ **0 stocks added**
❌ **All stocks rejected by fine_selection()**

---

## Complete Scenario Flow:

### **INTENDED FLOW (What Should Happen):**

`
1. INITIALIZATION PHASE
  ├─ initialize() called
  ├─ Set timezone to New York
  ├─ Register Universe Selection (coarse + fine)
  ├─ Try to load from ObjectStore
  │  ├─ If found: Load 585 stocks → Add manually → System ready
  │  └─ If not found: Wait for Universe Selection
  └─ Schedule events (heartbeat, daily report, etc.)

2. UNIVERSE SELECTION PHASE (Runs at 00:00-00:30 AM EST daily)
  ├─ coarse_selection() called
  │  ├─ Receive ~10,000 stocks from QuantConnect
  │  ├─ Filter by price ($1-$50)
  │  ├─ Filter by has_fundamental_data
  │  └─ Return ~3,000 symbols to fine_selection()
  │
  ├─ fine_selection() called
  │  ├─ Receive ~3,000 stocks from coarse
  │  ├─ For each stock:
  │  │  ├─ Get shares_outstanding via _get_shares_outstanding()
  │  │  ├─ Get market_cap from x.MarketCap
  │  │  ├─ Filter: shares <= 30M AND 5M <= market_cap <= 100M
  │  │  └─ Add to filtered list if passes
  │  ├─ Sort by shares_outstanding (lowest first)
  │  ├─ Take top 900 stocks
  │  └─ Return 900 symbols to QuantConnect
  │
  └─ on_securities_changed() called
     ├─ Receive 900 stocks from QuantConnect
     ├─ For each stock:
     │  ├─ Create SymbolData object
     │  ├─ Subscribe to BenzingaNews
     │  ├─ Calculate average volume (ADV)
     │  └─ Add to symbol_data_dict
     └─ Save list to ObjectStore for next run

3. DATA PROCESSING PHASE (Continuous during market hours)
  ├─ on_data() called every minute
  │  ├─ Update SPY price
  │  ├─ Process Telegram alert queue
  │  ├─ Call news_analyzer.process_news()
  │  │  ├─ Check for new Benzinga news in slice_data
  │  │  ├─ For each news item:
  │  │  │  ├─ Evaluate importance (critical/important/normal/low)
  │  │  │  ├─ Open news window (5 minutes)
  │  │  │  ├─ Store news in symbol_data.pending_news
  │  │  │  └─ Mark symbol as in_news_window
  │  │  └─ Close expired news windows
  │  │
  │  └─ For each stock in symbol_data_dict:
  │     ├─ Update price from bar.close
  │     ├─ Update volume from bar.volume
  │     ├─ Calculate RVOL (relative volume)
  │     └─ Call _check_for_signals()

4. SIGNAL CHECKING PHASE (For stocks with active news)
  ├─ _check_for_signals() called
  │  ├─ Check if stock is in news window → If NO: return
  │  ├─ Check cooldown period → If in cooldown: return
  │  │
  │  ├─ If news_alert_sent == False:
  │  │  └─ Call _send_news_alert()
  │  │     ├─ Extract headline and URL from news
  │  │     ├─ Build news alert message
  │  │     ├─ Queue alert with priority (critical/high)
  │  │     └─ Mark news_alert_sent = True
  │  │
  │  └─ If reaction_alert_sent == False:
  │     └─ Call _check_reaction_alert()

5. REACTION CHECKING PHASE (Check if stock reacted to news)
  ├─ _check_reaction_alert() called
  │  ├─ Calculate metrics:
  │  │  ├─ volume_spike_ratio = current_volume / avg_volume
  │  │  ├─ rvol = session_volume / expected_volume
  │  │  └─ price_change = (current_price - news_price) / news_price * 100
  │  │
  │  ├─ Get dynamic thresholds based on:
  │  │  ├─ News importance (critical/important/normal/low)
  │  │  └─ Time of day (pre_market/opening/lunch/power_hour/after_market)
  │  │
  │  ├─ Apply defensive filters:
  │  │  ├─ Extreme volatility filter (>10% move)
  │  │  ├─ Minimum move filter (<1% move)
  │  │  └─ SPY correlation filter (market-wide move)
  │  │
  │  ├─ Check conditions:
  │  │  ├─ Volume condition: spike_ratio >= threshold AND rvol >= threshold
  │  │  └─ Price condition: abs(price_change) >= threshold
  │  │
  │  └─ If BOTH conditions met:
  │     ├─ Build reaction alert message
  │     ├─ Queue alert with priority (high/critical)
  │     ├─ Mark reaction_alert_sent = True
  │     └─ Update alert statistics

6. ALERT DELIVERY PHASE
  ├─ notifier.process_queue() called
  │  ├─ Check rate limits (20 messages/minute)
  │  ├─ Process alerts by priority:
  │  │  ├─ Critical queue first
  │  │  ├─ High queue second
  │  │  ├─ Normal queue third
  │  │  └─ Low queue last
  │  │
  │  └─ For each alert:
  │     ├─ Send to Telegram via API
  │     ├─ Wait 3 seconds between messages
  │     └─ Update statistics
  │
  └─ User receives alert on Telegram
`

---

### **ACTUAL FLOW (What's Happening Now):**

`
1. INITIALIZATION PHASE ✅
  ├─ initialize() called ✅
  ├─ Universe Selection registered ✅
  ├─ ObjectStore loaded 585 stocks ✅
  └─ BUT: Rejected ObjectStore stocks ❌
      └─ Reason: Unknown condition prevents usage

2. UNIVERSE SELECTION PHASE ⚠️
  ├─ coarse_selection() called ✅
  │  ├─ Received 10,334 stocks ✅
  │  ├─ Filtered to 3,119 stocks ✅
  │  └─ Sent 3,119 stocks to fine_selection ✅
  │
  ├─ fine_selection() called ✅
  │  ├─ Received 3,119 stocks ✅
  │  ├─ Applied filters ✅
  │  └─ Result: 0 stocks passed ❌
  │     └─ Reason: ALL stocks rejected by filter
  │
  └─ on_securities_changed() called ⚠️
     ├─ Received 0 stocks ❌
     └─ symbol_data_dict remains empty ❌

3. DATA PROCESSING PHASE ❌
  ├─ on_data() called ✅
  └─ BUT: No stocks to process ❌
      └─ symbol_data_dict is empty

4. SIGNAL CHECKING PHASE ❌
  └─ Never reached (no stocks in universe)

5. REACTION CHECKING PHASE ❌
  └─ Never reached (no stocks in universe)

6. ALERT DELIVERY PHASE ❌
  └─ Never reached (no signals to check)

RESULT: System runs but does nothing ❌
`

---

## Code Implementation:

### 1. ∈itialize() Function:

pythondef∈itialize(self):  Initialize the algorithm  try:    #Basicse∈gs    self.set⋆tdate(2024,1,1)    self.setcash(100000)    self.settimezo≠(TimeZo≠s.NEWYORK)        #Initializedictionaries    self.symboldatadict={}        #Subsystems    self.¬ifier=Te≤gramNotifier(self)    self.≠wsanalyzer=NewsAnalyzer(self)    self.transla→r=TranslationService(self)        #Systemstate    self.iswarmedup=False    self.b∞tstrapcomp≤ted=False    self.universeupdatescount=0        #AddSPYformarketcorrelationfi<er    self.spysymbol=self.addequity(SPY,Resolution.MINUTE).symbol    self.spypriceat≠ws={}    self.spycurrentprice=0        #RegisterUniverseSe≤ction    self.log([Initialize] Setting up Universe Selection...)    self.universese∈gs.resolution=Resolution.DAILY    self.adduniverse(self.coarsese≤ction,self.f∈ese≤ction)    self.log([Initialize] Universe Selection registered successfully)        #Try→loadomObjectS→reforimmediate⋆t    ifconfig.USEOBJECTSTORE:      self.log([Initialize] ObjectStore enabled - attempting immediate loading...)      ifself.loadtar≥tsymbolsomobjects→re():        self.log(f[Initialize] Loaded {len(self.target_symbols)} stocks from ObjectStore)        self.addmaνaluniverse()        self.b∞tstrapcomp≤ted=True        self.log([Initialize] Immediate loading complete! System ready.)      else:        self.log([Initialize] No saved list - will wait for Universe Selection (00:00-00:30 AM))    else:      self.log([Initialize] ObjectStore disabled - will wait for Universe Selection)        self.log([Initialize] Wait 5-20 minutes for fundamental data and Universe Selection...)    self.log([Initialize] [CoarseSelection] and [FineSelection] logs will appear when loading starts)        #Schede–events    self.schede–events()        #Send⋆tupmessa≥(LiveModeonly)    ifself.livemode:      self.log([Initialize] Live Mode - sending startup message...)      self.¬ifier.send⋆tupmessa≥withretry()      self.¬ifier.processqueue()        self.log([Initialize] Initialize completed successfully)      exceptExceptionase:    self.error(f[Initialize] Critical error: {e})    raise

---

### 2. _loadtar≥tsymbolsomobjects→re()Function:

pythondefloadtar≥tsymbolsomobjects→re(self):  Load target symbols list from ObjectStore  try:    ifself.objects→re.conta∈skey(config.OBJECTSTOREKEY):      symbolsstr=self.objects→re.read(config.OBJECTSTOREKEY)      self.tar≥tsymbols=symbolsstr.split(',')      self.log(f[ObjectStore] Loaded {len(self.target_symbols)} stocks)      returnTrue #✅Suesl–yloaded    else:      self.log([ObjectStore] No saved list found - using Universe Selection)      returnFalse #❌Nosavedlist  exceptExceptionase:    self.error(f[ObjectStore] Error loading: {e})    returnFalse

**QUESTION 1:** The logs show [ObjectS→re]Loaded585s→cks but then [Initialize]Nosavedlist. What condition prevents using the loaded stocks?

---

### 3. _addmaνaluniverse() Function:

pythondefaddmaνaluniverse(self):  Add stocks manually from saved list with duplicate protection  try:    if¬hasar(self,'tar≥tsymbols')or¬self.tar≥tsymbols:      self.log([ManualUniverse] No stock list to add)      return        self.log(f[ManualUniverse] Starting to add {len(self.target_symbols)} stocks manually...)        addedcount=0    skippedcount=0        forticker∈self.tar≥tsymbols:      try:        #Checkforduplicates        eξst∈gsymbol=No≠        forsymbol∈self.symboldatadict.keys():          ifsymbol.value==ticker:            eξst∈gsymbol=symbol            break                ifeξst∈gsymbol:          skippedcount+=1          cont∈ue                #Adds→ck        symbol=self.addequity(ticker,Resolution.MINUTE).symbol        self.symboldatadict[symbol]=SymbolData(self,symbol)                #Subscribe→Benz∈ga        self.adddata(Benz∈gaNews,symbol)                #Calca––teADV        self.calca––teavera≥volume(symbol)                addedcount+=1              exceptExceptionase:        self.error(f[ManualUniverse] Failed to add {ticker}: {e})        self.log(f[ManualUniverse] Successfully added {added_count} stocks (Skipped {skipped_count} duplicates))    self.log(f[ManualUniverse] Total active stocks: {len(self.symbol_data_dict)})      exceptExceptionase:    self.error(f[ManualUniverse] Error: {e})

---

### 4. coarsese≤ction() Function:

pythondefcoarsese≤ction(self,coarse):      Coarse Universe Selection - called automatically in Live Mode        Selects best UNIVERSE_SIZE stocks based on:    - Price (MIN_PRICE - MAX_PRICE)    - Has fundamental data      try:    coarselist=list(coarse)        self.log(f[CoarseSelection] called at {self.time})    self.log(f[CoarseSelection] Starting Coarse Selection - Time: {self.time})    self.log(f[CoarseSelection] Total available stocks: {len(coarse_list)})        #Fi<erbypriceonly(novolumefi<er)    fi<ered=[      xforx∈coarselist      ifconfig.MINPRICE≤x.price≤config.MAXPRICE      andx.hasfundamentaldata    ]        self.log(f[CoarseSelection] After price filter: {len(filtered)} stocks)    self.log(f[CoarseSelection] Sending all stocks to Fine Selection (no limit))        #Sendalls→cks→F∈eSe≤ction(no900limithere)    return[x.symbolforx∈fi<ered]      exceptExceptionase:    self.error(f[CoarseSelection] Error: {e})    return[]

**Criteria:**
- MINPRICE=1.0
- MAXPRICE=50.0

**Result:** ✅ Successfully filters ~3,000 stocks and sends to fine_selection

---

### 5. f∈ese≤ction() Function:

pythondeff∈ese≤ction(self,f∈e):      Fine Universe Selection - called automatically after Coarse Selection        Applies additional filter based on:    - Shares Outstanding (MAX_SHARES_OUTSTANDING)    - Market Cap (MIN_MARKET_CAP - MAX_MARKET_CAP)      try:    f∈elist=list(f∈e)        self.log(f[FineSelection] called at {self.time})    self.log(f[FineSelection] Starting Fine Selection - Time: {self.time})    self.log(f[FineSelection] Received {len(fine_list)} stocks from Coarse Selection)        #Fi<erbyMarketCap+SharesOutstand∈g    fi<ered=[]    debugcount=0        forx∈f∈elist:      try:        sharesoutstand∈g=self.≥tsharesoutstand∈g(x)        market∩=x.MarketCapifhasar(x,'MarketCap')else0                #Pr∫first10s→cksfordebugg∈g        ifdebugcount<10:          omhelpersimportsafeformat          sharesstr=safeformat(sharesoutstand∈g,,.0f,logwarn∈g=True,                       algo=self,fieldname=f{x.symbol.value}_shares)          market∩_str=$+safeformat(market∩,,.0f,logwarn∈g=True,                            algo=self,fieldname=f{x.symbol.value}_market_cap)          self.log(f[FineSelection] {x.symbol.value}: Shares={shares_str}, MarketCap={market_cap_str})          debugcount+=1                #Fi<er:MarketCap+SharesOutstand∈g        if(sharesoutstand∈gandsharesoutstand∈g≤config.MAXSHARESOUTSTANDING          andmarket∩≥config.MINMARKETCAP          andmarket∩≤config.MAXMARKETCAP):          fi<ered.append(xsharesoutstand∈g)                exceptExceptionase:        ifdebugcount<10:          self.log(f[FineSelection] {x.symbol.value}: Error - {e})          debugcount+=1        cont∈ue        self.log(f[FineSelection] After Market Cap + Shares filter: {len(filtered)} stocks)        #SortbySharesOutstand∈g(lowestfirst−LowFloat)    sortedbyshares=sorted(fi<ered,key=λx:x[1])        #Se≤ctbest900s→cks    se≤cted=[x[0].symbolforx∈sortedbyshares[:config.UNIVERSESIZE]]        self.log(f[FineSelection] After sorting: Selected best {len(selected)} stocks (Low Float))    self.log(f[FineSelection] Fine Selection complete - Sending {len(selected)} stocks to on_securities_changed)        returnse≤cted      exceptExceptionase:    self.error(f[FineSelection] Error: {e})    return[]

**Criteria:**
- MAXSHARESOUTSTANDING=30000_000(30 million shares)
- MINMARKETCAP=5000_000 ($5M)
- MAXMARKETCAP=100000_000 ($100M)
- UNIVERSESIZE=900

**Result:** ❌ Returns 0 stocks (ALL rejected by filter)

---

### 6. _≥tsharesoutstand∈g() Function:

pythondef≥tsharesoutstand∈g(self,f∈efundamental):  Extract shares outstanding (free float)  try:    #Aempt1:CompanyReference.SharesOutstand∈g    ifhasar(f∈efundamental,'CompanyReference')and      hasar(f∈efundamental.CompanyReference,'SharesOutstand∈g'):      shares=f∈efundamental.CompanyReference.SharesOutstand∈g      ifsharesandshares>0:        returnshares        #Aempt2:Earn∈gReports.BasicAvera≥Shares    ifhasar(f∈efundamental,'Earn∈gReports')and      hasar(f∈efundamental.Earn∈gReports,'BasicAvera≥Shares'):      shares=f∈efundamental.Earn∈gReports.BasicAvera≥Shares.ThreeMonths      ifsharesandshares>0:        returnshares        #Aempt3:F∈ancialStatements.SharesOutstand∈g    ifhasar(f∈efundamental,'F∈ancialStatements')and      hasar(f∈efundamental.F∈ancialStatements,'SharesOutstand∈g'):      shares=f∈efundamental.F∈ancialStatements.SharesOutstand∈g.ThreeMonths      ifsharesandshares>0:        returnshares        #Aempt4:CompanyProfi≤.SharesOutstand∈g    ifhasar(f∈efundamental,'CompanyProfi≤')and      hasar(f∈efundamental.CompanyProfi≤,'SharesOutstand∈g'):      shares=f∈efundamental.CompanyProfi≤.SharesOutstand∈g      ifsharesandshares>0:        returnshares        returnNo≠      exceptExceptionase:    returnNo≠

**QUESTION 2:** Are these methods correct for accessing shares outstanding in QuantConnect? Is there a better/more reliable way?

---

### 7. onsecuritieschan≥d() Function:

pythondefonsecuritieschan≥d(self,chan≥s):  Handle changes in monitored stocks  try:    self.universeupdatescount+=1        addedcount=≤n(chan≥s.addedsecurities)    removedcount=≤n(chan≥s.removedsecurities)        self.log(fOnSecuritiesChanged at {self.time}: Added {added_count}, Removed {removed_count})    self.log(f[OnSecuritiesChanged] Time: {self.time})    self.log(f[OnSecuritiesChanged] Update #{self.universe_updates_count} | Added: {added_count} | Removed: {removed_count})        #Add≠ws→cks    foradded∈chan≥s.addedsecurities:      symbol=added.symbol            #SkipSPY(addedmaνally∈∈itialize)      ifsymbol==self.spysymbol:        cont∈ue            #CreateSymbolData      self.symboldatadict[symbol]=SymbolData(self,symbol)            #Subscribe→Benz∈ga      try:        self.adddata(Benz∈gaNews,symbol)        self.log(f[OnSecuritiesChanged] Added {symbol.value} + Benzinga)      exceptExceptionase:        self.error(f[OnSecuritiesChanged] Failed Benzinga subscription for {symbol}: {e})            #Calca––teavera≥volume      self.calca––teavera≥volume(symbol)        #Removeolds→cks    forremoved∈chan≥s.removedsecurities:      symbol=removed.symbol            #NeverremoveSPY      ifsymbol==self.spysymbol:        cont∈ue            ifsymbol∈self.symboldatadict:        #C≤aνp        self.symboldatadict[symbol].dispose()        ∂self.symboldatadict[symbol]        self.log(f[OnSecuritiesChanged] Removed {symbol.value})        self.log(f[OnSecuritiesChanged] Total active stocks: {len(self.symbol_data_dict)})        #Markb∞tstrapcomp≤te    if¬self.b∞tstrapcomp≤tedand≤n(self.symboldatadict)>0:      self.b∞tstrapcomp≤ted=True      self.log(f[OnSecuritiesChanged] Initial loading complete! Successfully loaded {len(self.symbol_data_dict)} stocks)      self.log(f[OnSecuritiesChanged] System now ready to monitor news and send alerts)            #SendTe≤grama≤rtwhenload∈gcomp≤te(LiveModeonly)      ifself.livemodeand≤n(self.symboldatadict)≥10:        msg=(          f✅ Initial Loading Complete!\n\n          f📊 Stocks Loaded: {len(self.symbol_data_dict)}\n          f⏱ Time: {self.time.strftime('%Y-%m-%d %H:%M:%S')}\n          f🔔 System now ready to monitor news\n        )        self.¬ifier.queuea≤rt(msg,priority=normal)        self.¬ifier.processqueue()        #Save≠wlist→ObjectS→refor≠xtrun    ifconfig.USEOBJECTSTOREandself.universeupdatescount≥1:      try:        symbolslist=[symbol.valueforsymbol∈self.symboldatadict.keys()                ifsymbol≠self.spysymbol]        if≤n(symbolslist)>0:          symbolsstr=','.jo∈(symbolslist)          self.objects→re.save(config.OBJECTSTOREKEY,symbolsstr)          self.log(f[ObjectStore] Saved {len(symbols_list)} stocks for next run)      exceptExceptionase:        self.error(f[ObjectStore] Error saving: {e})      exceptExceptionase:    self.error(f[OnSecuritiesChanged] Error: {e})

**Result:** Currently receives 0 stocks, so symbol_data_dict remains empty

---

### 8. ondata() Function:

pythondefondata(self,slicedata):  Process incoming data  try:    self.dataupdatescount+=1        #Diagnosticmessa≥onfirstcall    ifself.dataupdatescount==1:      self.log(f[OnData] First call | Time: {self.time})      self.log(f[OnData] Active stocks: {len(self.symbol_data_dict)})        #UpdateSPYprice    ifself.spysymbol∈slicedata.s¯:      self.spycurrentprice=slicedata.s¯[self.spysymbol].close        #Processa≤rtqueue    self.¬ifier.processqueue()        #Process≠ws    self.≠wsanalyzer.process≠ws(slicedata,self.symboldatadict)        #C≤anexpired≠wsw∈dows    self.≠wsanalyzer.closeexpired≠wsw∈dows(self.utctime,self.symboldatadict)        #Processs→cks    forsymbol,symboldata∈self.symboldatadict.items():      ifsymbol¬∈slicedata.s¯:        cont∈ue            =¯¯¯slicedata.s¯[symbol]            #Updatedata      symboldata.updateprice(.¯close)      symboldata.updatevolume(.¯volume)            #Calca––teRVOL      symboldata.calca––tervol(        self.utctime,        config.SESSIONSTARTMIN,        config.SESSIONMINUTES      )            #Checkforsignals      self.checkforsignals(symbol,symboldata)      exceptExceptionase:    self.error(f[OnData] Error: {e})

---

### 9. ≠wsanalyzer.process≠ws() Function:

pythondefprocess≠ws(self,slicedata,symboldatadict):  Process Benzinga news from slice data  try:    #Checkifslicehas≠wsdata    if¬hasar(slicedata,'data')or¬slicedata.data:      return        #Iteratethroughalldata∈slice    forsymbol,datalist∈slicedata.data.items():      #Skipif¬∈ouruniverse      ifsymbol¬∈symboldatadict:        cont∈ue            symboldata=symboldatadict[symbol]            #Processeachdataitem      fordataitem∈datalist:        #Checkifit'sBenz∈ga≠ws        if¬isinstance(dataitem,Benz∈gaNews):          cont∈ue                #Evaluate≠wsimportance        evaluation=self.evaluateimportance(dataitem)                #Open≠wsw∈dow        symboldata.open≠wsw∈dow(          self.alg⊙utctime,          config.NEWSWATCHWINDOW        )                #S→re≠ws        symboldata.pend∈g≠ws.append({          news_item:dataitem,          evaluation:evaluation,          time:self.alg⊙utctime        })                #Log        headl∈e=self.≥theadl∈e(dataitem)        self.alg⊙log(f📰 [News] {symbol.value}: {evaluation['level_ar']} - {headline[:50]}...)                self.≠wsprocessed→day+=1        self.≠wsw∈dowsope≠d→day+=1          exceptExceptionase:    self.alg⊙error(f[ProcessNews] Error: {e})

---

### 10. _checkforsignals() Function:

pythondefcheckforsignals(self,symbol,symboldata):  Check for alert signals  try:    #Ifs→ckis∈≠wsw∈dow    if¬symboldata.is∈_≠wsw∈dow(self.utctime):      return        #Checkc∞ldownperiod    if¬symboldata.cansenda≤rt(self.utctime):      return        #Sendimmediatea≤rtwhen≠wsbreaks(onceonly)    if¬symboldata.≠wsa≤rtsentandsymboldata.pend∈g≠ws:      self.send≠wsa≤rt(symbol,symboldata)        #Checkfors→ckreaction→≠ws    if¬symboldata.reactiona≤rtsent:      self.checkreactiona≤rt(symbol,symboldata)        exceptExceptionase:    self.error(f[CheckSignals] Error for {symbol}: {e})

---

### 11. _send≠wsa≤rt() Function:

pythondefsend≠wsa≤rt(self,symbol,symboldata):  Send immediate news alert  try:    ≠wsdata=symboldata.pend∈g≠ws[0]    ≠wsitem=≠wsdata[news_item]    evaluation=≠wsdata.≥t(evaluation)        #Extract≠wsdetails    headl∈e=self.≥theadl∈e(≠wsitem)    url=self.≥t≠wsurl(≠wsitem)        #SaveSPYpriceat≠wstime    self.spypriceat≠ws[symbol]=self.spycurrentprice        #Builda≤rt    msg=self.¬ifier.build≠wsa≤rt(      symbol,symboldata,headl∈e,url,evaluation    )        #Determineprioritybasedon≠wsimportance    priority=criticalifevaluationandevaluation['≤vel']==criticalelsehigh        self.¬ifier.queuea≤rt(msg,priority=priority)    symboldata.≠wsa≤rtsent=True    symboldata.marka≤rtsent(self.utctime)        self.log(f📱 [NewsAlert] {symbol.value} [{evaluation['level_ar'] if evaluation else 'News'}])      exceptExceptionase:    self.error(f[SendNewsAlert] Error for {symbol}: {e})

---

### 12. _checkreactiona≤rt() Function:

pythondefcheckreactiona≤rt(self,symbol,symboldata):  Check if stock reacted to news  try:    self.log(f⚡ [CheckReaction] {symbol.value} | Price: ${symbol_data.current_price:.2f} | RVOL: {symbol_data.current_rvol:.2f})        #Defensiveprotection−checkformissingvalues    ifsymboldata.currentpriceisNo≠orsymboldata.currentprice≤0:      return        #Get≠wsevaluation    evaluation=No≠    ifsymboldata.pend∈g≠ws:      evaluation=symboldata.pend∈g≠ws[0].≥t(evaluation)        #Getdynamicthresholds    importance≤vel=evaluation['importance≤vel']ifevaluationelse2        omhelpersimport≥ttimeofdayperiod    timeperiod=≥ttimeofdayperiod(self.time)        thresholds=config.≥tdynamicthresholds(importance≤vel,timeperiod)    volumesπkethreshold,rvolthreshold,pricechan≥threshold=thresholds        #Calca––temetrics    hassπke,sπkeratio=symboldata.checkvolumesπke()    rvol=symboldata.currentrvol    pricechan≥=symboldata.calca––tepricechan≥percent()        #Defensiveprotection−checkforNaN    importmath    ifmath.isnan(pricechan≥):      return        #Getadaptivethresholds    adaptivemin_move=symboldata.≥tadaptivemin_move()    adaptiveextremevol=symboldata.≥tadaptiveextremevolatilitythreshold()        #Extremevolatilityfi<er(adaptive)    if|pricechan≥|>adaptiveextremevol:      self.rejecteda≤rtsstats[extreme_vol]+=1      self.log(f[Rejected-ExtremeVol] {symbol.value}: {price_change:.2f}% > {adaptive_extreme_vol:.2f}% (adaptive) - Extreme volatility, ignored)      return        #M∈iμmmovefi<er(adaptive)    if|pricechan≥|<adaptivemin_move:      self.rejecteda≤rtsstats[min_move]+=1      return        #CheckforU<ra−High−Confncefirst(beforeSPYfi<er)    ist–rahigh=self.checkt–rahighconfnce(symbol,thresholds)        ifist–rahigh:      #Checkc∞ldownbeforesend∈gUHCa≤rt      if¬symboldata.cansenda≤rt(self.utctime,isuhc=True):        self.rejecteda≤rtsstats[cooldown]+=1        return            #U<ra−High−Confncea≤rt(all∈dica→rsconfirmed)      headl∈e,url=No≠,No≠      ifsymboldata.pend∈g≠ws:        ≠wsitem=symboldata.pend∈g≠ws[0][news_item]        headl∈e=self.≥theadl∈e(≠wsitem)        url=self.≥t≠wsurl(≠wsitem)            msg=self.¬ifier.buildt–rahighconfncea≤rt(        symbol,symboldata,sπkeratio,rvol,pricechan≥,        headl∈e,url,evaluation      )            self.¬ifier.queuea≤rt(msg,priority=critical)      symboldata.reactiona≤rtsent=True      symboldata.marka≤rtsent(self.utctime)      self.a≤rtssentstats[uhc]+=1            self.log(f🚨 [UltraHighConfidence] {symbol.value}: Alert sent!)      return        #SPYfi<er(afterUHCcheck)    spycorrelation=self.checkspycorrelation(symbol,pricechan≥)    ifspycorrelation:      self.rejecteda≤rtsstats[spy_correlation]+=1      return        #Rega––rANDORlogic(if¬U<ra−High)    volumecondition=(hassπkeandsπkeratio≥volumesπkethresholdand              rvol≥rvolthreshold)    pricecondition=|pricechan≥|≥pricechan≥threshold        ifvolumeconditionandpricecondition:      #Sendreactiona≤rt      headl∈e,url=No≠,No≠      ifsymboldata.pend∈g≠ws:        ≠wsitem=symboldata.pend∈g≠ws[0][news_item]        headl∈e=self.≥theadl∈e(≠wsitem)        url=self.≥t≠wsurl(≠wsitem)            msg=self.¬ifier.buildreactiona≤rt(        symbol,symboldata,sπkeratio,rvol,pricechan≥,        headl∈e,url,evaluation      )            self.¬ifier.queuea≤rt(msg,priority=high)      symboldata.reactiona≤rtsent=True      symboldata.marka≤rtsent(self.utctime)      self.a≤rtssentstats[regular]+=1            self.log(f📈 [ReactionAlert] {symbol.value}: Alert sent!)      exceptExceptionase:    self.error(f[CheckReaction] Error for {symbol}: {e})

---

### 13. ¬ifier.buildreactiona≤rt() and processqueue():

`python
def build_reaction_alert(self, symbol, symbol_data, spike_ratio, rvol, price_change, 
                       headline, url, evaluation):
   """Build reaction alert message"""
   msg = (
       f"📈 Stock Reaction Alert\n\n"
       f"━━━━━━━━━━━━━━━━━━━━\n"
       f"📌 Symbol: {symbol.value}\n"
       f"💰 Price: ${symbol_data.current_price:.2f}\n"
       f"📊 Change: {price_change:+.2f}%\n"
       f"📈 Volume Spike: {spike_ratio:.1f}x\n"
       f"🔥 RVOL: {rvol:.2f}\n"
       f"━━━━━━━━━━━━━━━━━━━━\n"
   )
   
   if headline:
       msg += f"📰 News: {headline[:100]}\n"
   
   if url:
       msg += f"🔗 Link: {url}\n"
   
   msg += f"\n⏰ Time: {self.algo.time.strftime('%Y-%m-%d %H:%M:%S')}\n"
   msg += f"📰 News Group"
   
   return msg

def process_queue(self):
   """Process alert queue with priority and rate limiting"""
   try:
       # Check rate limits (20 messages/minute)
       current_time = self.algo.time
       
       # Remove old timestamps (older than 1 minute)
       while self.messages_sent_last_minute and \
             (current_time - self.messages_sent_last_minute[0]).total_seconds() > 60:
           self.messages_sent_last_minute.popleft()
       
       # Check if we can send more messages
       if len(self.messages_sent_last_minute) >= self.max_messages_per_minute:
           return  # Rate limit reached
       
       # Process queues by priority
       queues = [
           (self.critical_queue, "critical"),
           (self.high_queue, "high"),
           (self.normal_queue, "normal"),
           (self.low_queue, "low")
       ]
       
       for queue, priority in queues:
           if len(queue) > 0:
               message = queue.popleft()
               
               # Send to Telegram
               success = self._send_to_telegram(message)
               
               if success:
                   self.alerts_sent_today += 1
                   self.messages_sent_last_minute.append(current_time)
                   self.last_message_sent = message
                   self.last_message_time = current_time
               else:
                   self.alerts_failed_today += 1
               
               # Wait 3 seconds between messages
               time.sleep(3)
               
               # Only send one message per call
               break
       
   except Exception as e:
       self.algo.error(f"[ProcessQueue] Error: {e}")
`

---

## Specific Questions:

### **QUESTION 1: Why does f∈ese≤ction()reject ALL stocks?**
- Is the problem with MAXSHARESOUTSTANDING=30M (too low)?
- Is fundamental data unavailable for most stocks?
- Is there a better way to get sharesoutstand∈g?
- Should I use FreeFloat instead of SharesOutstand∈g?

### **QUESTION 2: Is there a timing issue with Universe Selection?**
- Logs show coarsese≤ction() is called at 02:00:00(2 AM EST)
- Is this correct? Should it be called at 00:00−00:30AM?
- Why does it take 5 hours from initialize (00:41) to coarse_selection (06:00)?

### **QUESTION 3: Why doesn't ObjectStore work?**
- Logs show: [ObjectS→re]Loaded585s→cks
- But then: [Initialize]Nosavedlist−willwaitforUniverseSe≤ction
- What condition prevents using the loaded stocks?
- Is there a return value check missing?

### **QUESTION 4: Is there an error in _≥tsharesoutstand∈g()?**
- Are the methods used (CompanyReference.SharesOutstand∈g, Earn∈gReports.BasicAvera≥Shares, etc.) correct?
- Is there a more reliable way to access this data?
- Should I log which method succeeds for debugging?

### **QUESTION 5: What are reasonable values for MAXSHARESOUTSTANDING?**
- Current value: 30M shares
- Is this too restrictive for QuantConnect data?
- What percentage of stocks have shares_outstanding <= 30M?
- Should I increase to 100M or 500M?

### **QUESTION 6: How can I diagnose the problem more accurately?**
- What additional logs should I add?
- Should I print sharesoutstand∈g and market∩ for first 50 stocks?
- Is there a way to check data availability before filtering?
- Should I add a fallback filter if fundamental data is missing?

---

## Ultimate Goal:

I want the system to work as follows:

1. **First Run:** System selects 900 stocks (Low Float) via Universe Selection
2. **Second Run:** System loads list from ObjectStore immediately (1-2 minutes)
3. **When News Breaks:** Send immediate alert via Telegram
4. **When Stock Reacts:** Send second alert based on RVOL and price movement

---

## Additional Notes:

- System runs in **Live Mode** on QuantConnect
- Using **Benzinga News** as news source
- Target: **Micro-cap stocks** (<$100M market cap) with **Low Float** (<30M shares outstanding)
- Old version worked, but after modifying code to use Universe Selection, it stopped adding stocks
- The complete flow from stock appearance to user alert is described above

---

## Please Help With:

1. Identify the **root cause** of why all stocks are rejected in f∈ese≤ction()
2. Suggest **practical solutions** to fix the problem
3. Explain **best practices** for using Universe Selection with Fundamental Data in QuantConnect
4. Clarify how to **diagnose** the problem more accurately (additional logs, values to print, etc.)
5. Confirm if the **complete scenario flow** I described is correct for QuantConnect

Thank you very much