# Follow-up Question: KeyError in Manual Indicator Warm-up & Additional Questions

Hello again,

Thank you for the excellent guidance on batch rotation and indicator management. I've implemented your recommendations, but encountered a **KeyError** during manual warm-up. I also have additional questions about best practices.

---

## Problem Encountered: KeyError in Manual Warm-up

### Error Details

`
Runtime Error: Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception.

at create_phase1_indicators
self.warm_up_indicator(symbol, self.phase1_obv_indicators[symbol], Resolution.MINUTE)
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
in main.py: line 451

at initialize_batch
self.create_phase1_indicators(symbol)
in main.py: line 382

at rotate_batch
self.initialize_batch(self.current_batch_index)
in main.py: line 423
`

### Current Implementation (Following Your Advice)

I implemented manual warm-up as you suggested:

pythondefcreatephase1∈dica→rs(self,symbol):  Create Phase 1 indicators with manual warm-up (Bot recommendation #5)  ∈dica→rscreated=[]    try:    #Checkliqutyfirst(Botrecommendation#3)    his→ry=self.his→ry(symbol,max(self.RDVPERIOD,self.CMFPERIOD,5),Resolution.MINUTE)    ifhis→ry.emptyor≤n(his→ry)<2:      self.debug(f[SKIP-ILLIQUID] {symbol.value} | No sufficient history data)      returnFalse        #CreateRDVwithseparateerrorhandl∈g    try:      rdv=self.rdv(symbol,self.RDVPERIOD,Resolution.MINUTE)      #Maνalwarm−up(Botrecommendation#5)      fortime,row∈his→ry.iterrows():        if'close'∈rowandrow['close']>0:          rdv.update(time,row['close'])      self.phase1rdv∈dica→rs[symbol]=rdv      ∈dica→rscreated.append(fRDV(ready={rdv.is_ready}, samples={rdv.samples}))    exceptExceptionase:      self.error(f[ERROR] Failed to create RDV for {symbol.value}: {str(e)})        #CreateCMFwithseparateerrorhandl∈g    try:      cmf=self.cmf(symbol,self.CMFPERIOD,Resolution.MINUTE)      #Maνalwarm−up      fortime,row∈his→ry.iterrows():        ifall(k∈rowfork∈['close','high','low','volume']):          cmf.update(TradeBar(time,symbol,row['open'],row['high'],                    row['low'],row['close'],row['volume']))      self.phase1cmf∈dica→rs[symbol]=cmf      ∈dica→rscreated.append(fCMF(ready={cmf.is_ready}, samples={cmf.samples}))    exceptExceptionase:      self.error(f[ERROR] Failed to create CMF for {symbol.value}: {str(e)})        #CreateOBVwithseparateerrorhandl∈g    try:      obv=self.obv(symbol,Resolution.MINUTE)      #Maνalwarm−up      fortime,row∈his→ry.iterrows():        ifall(k∈rowfork∈['close','volume']):          obv.update(TradeBar(time,symbol,row['open'],row['high'],                    row['low'],row['close'],row['volume']))      self.phase1obv∈dica→rs[symbol]=obv      ∈dica→rscreated.append(fOBV(ready={obv.is_ready}, samples={obv.samples}))    exceptExceptionase:      self.error(f[ERROR] Failed to create OBV for {symbol.value}: {str(e)})        #Logrest–s    if∈dica→rscreated:      self.debug(f[IndicatorCreation-IMPROVED] {symbol.value} | {', '.join(indicators_created)})      returnTrue    else:      self.debug(f[SKIP-NO-INDICATORS] {symbol.value} | Failed to create any indicators)      returnFalse        exceptExceptionase:    self.error(f[ERROR] General error in create_phase1_indicators for {symbol.value}: {str(e)})    returnFalse

### Questions About the KeyError

1. **Why does the KeyError occur?**
  - The error happens at line 451 which seems to be the old warmup∈dica→r() call
  - But I thought I replaced all warmup∈dica→r() calls with manual warm-up
  - Could there be a caching issue or is the code not fully updated?

2. **Is my manual warm-up implementation correct?**
  - Am I creating TradeBar objects correctly for CMF and OBV?
  - Should I use TradeBar or just pass the row directly?
  - Do I need to handle missing OHLCV data differently?

3. **Should I check if indicator creation succeeded before adding to dictionary?**
  python #Currentapproach: obv=self.obv(symbol,Resolution.MINUTE) #...warmup... self.phase1obv∈dica→rs[symbol]=obv   #Beerapproach? obv=self.obv(symbol,Resolution.MINUTE) ifobvis¬No≠: #Checkifcreation≻eeded?   #...warmup...   self.phase1obv∈dica→rs[symbol]=obv

4. **What if indicator creation fails silently?**
  - Can self.rdv(), self.cmf(), or self.obv() return None?
  - Or do they always return an object even if data is insufficient?
  - How do I detect if indicator creation actually failed?

---

## Additional Questions

### 1. Indicator Update Methods

**Question:** What is the correct way to update different indicator types manually?

For RDV (price-based):
pythonrdv.update(time,row['close']) #✅Works?

For CMF and OBV (volume-based):
`python
# Option A: Create TradeBar
cmf.update(TradeBar(time, symbol, open, high, low, close, volume))

# Option B: Pass row directly?
cmf.update(time, row)

# Option C: Use different method?
cmf.update(TradeBar.from_dict(row))
`

Which approach is correct for each indicator type?

---

### 2. Handling Missing Data in History

**Question:** How should I handle incomplete or missing data in history?

Current approach:
pythonhis→ry=self.his→ry(symbol,10,Resolution.MINUTE)ifhis→ry.emptyor≤n(his→ry)<2:  returnFalse #Skipthissymbol

But what if:
- History has 10 rows but some have zero volume?
- History has gaps (missing minutes)?
- OHLC values are present but invalid (negative, NaN)?

Should I:
`python
# Clean the data first?
history = history[history['volume'] > 0]
history = history[history['close'] > 0]
history = history.dropna()

# Then check if enough data remains?
if len(history) < indicator.warm_up_period:
   return False
`

---

### 3. Indicator Readiness After Manual Warm-up

**Question:** After manual warm-up, should indicators be immediately ready?

Expected behavior:
pythonrdv=self.rdv(symbol,2,Resolution.MINUTE)#Maνallyfeed2s¯rdv.update(time1,close1)rdv.update(time2,close2)#Shod––rdv.isreadybeTruenow?

Or does isready only work with automatic data feed?

---

### 4. Best Practice for Indicator Creation Flow

**Question:** What is the recommended order of operations?

**Option A: Create → Store → Warm-up**
pythonrdv=self.rdv(symbol,2,Resolution.MINUTE)self.phase1rdv∈dica→rs[symbol]=rdv #S→refirst#Thenwarmupfortime,row∈his→ry.iterrows():  self.phase1rdv∈dica→rs[symbol].update(time,row['close'])

**Option B: Create → Warm-up → Store**
pythonrdv=self.rdv(symbol,2,Resolution.MINUTE)#Warmupfirstfortime,row∈his→ry.iterrows():  rdv.update(time,row['close'])#Thens→reself.phase1rdv∈dica→rs[symbol]=rdv

**Option C: Create → Warm-up → Verify → Store**
pythonrdv=self.rdv(symbol,2,Resolution.MINUTE)#Warmupfortime,row∈his→ry.iterrows():  rdv.update(time,row['close'])#Verifyitworkedifrdv.isreadyandrdv.samp≤s≥2:  self.phase1rdv∈dica→rs[symbol]=rdvelse:  self.debug(fRDV warm-up failed for {symbol.value})

Which option is best practice?

---

### 5. Error Recovery Strategy

**Question:** If indicator creation fails for one stock, what should I do?

**Current approach:**
- Try to create all 3 indicators
- If any fail, log error but continue
- Return True if at least one indicator was created

**Is this correct, or should I:**
- Return False if ANY indicator fails (all-or-nothing)?
- Keep partial indicators and mark the stock as "incomplete"?
- Retry indicator creation on next rotation?

---

### 6. Performance Optimization

**Question:** Is there a more efficient way to bulk warm-up indicators?

Current approach (per symbol):
pythonforsymbol∈batch:  his→ry=self.his→ry(symbol,10,Resolution.MINUTE)  #Createandwarmup∈dica→rs

Better approach (bulk request)?
python#Requesthis→ryforallsymbolsatonce?allhis→ry=self.his→ry(batchsymbols,10,Resolution.MINUTE)forsymbol∈batchsymbols:  symbolhis→ry=allhis→ry[symbol]  #Createandwarmup∈dica→rs

Does bulk history request improve performance?

---

### 7. Indicator Memory Management

**Question:** After removing a stock from the batch, how do I properly clean up indicators?

Current approach:
pythondefc≤aνpphase1∈dica→rs(self,symbol):  self.phase1rdv∈dica→rs.pop(symbol,No≠)  self.phase1cmf∈dica→rs.pop(symbol,No≠)  self.phase1obv∈dica→rs.pop(symbol,No≠)

Should I also:
python#Explicitlydisposeofthe∈dica→r?ifsymbol∈self.phase1rdv∈dica→rs:  ∈dica→r=self.phase1rdv∈dica→rs[symbol]  #∈dica→r.dispose()?  #∈dica→r.reset()?  ∂self.phase1rdv∈dica→rs[symbol]

Or is pop() sufficient for garbage collection?

---

### 8. Monitoring Warm-up Success Rate

**Question:** How can I track and optimize warm-up success rate?

Should I maintain statistics like:
pythonself.warμpstats={  '→talaempts':0,  '≻es′–:0,  'fai≤dnohis→ry':0,  'fai≤d∈dica→rcreation':0,  '∂≻ess':0}

And log them periodically:
python≻essrate=self.warμpstats'≻es′–self.warμpstats['→talaempts']self.log(f[WARMUP-STATS] Success rate: {success_rate:.1%})

Is this recommended for production strategies?

---

## Summary of Questions

1. Why does KeyError occur if I replaced warmup∈dica→r()?
2. Is my manual warm-up implementation correct?
3. How to properly update different indicator types?
4. How to handle missing/incomplete data in history?
5. Should indicators be immediately ready after manual warm-up?
6. What is the best order: Create → Store → Warm-up?
7. What error recovery strategy should I use?
8. Is bulk history request more efficient?
9. How to properly clean up indicators?
10. Should I track warm-up success rate?

---

## Context

- **Strategy Type**: Intraday with batch rotation
- **Batch Size**: 100 stocks
- **Rotation Interval**: 15 minutes (increased from 5)
- **Indicators**: RDV (period=2), CMF (period=3), OBV
- **Implementation**: Following your previous recommendations

Thank you for your continued guidance!