The issue in anomaly detection is that spy columns is a multiindex with levels “Price” and “Ticker”, but ticker is the empty string in some cases. Add this right before the error to check:
st.write(str(spy.columns))
It shows:
MultiIndex([('Adj Close', 'SPY'), ( 'Close', 'SPY'), ( 'High', 'SPY'), ( 'Low', 'SPY'), ( 'Open', 'SPY'), ( 'Volume', 'SPY'), ( 'SMA', ''), ( 'STD', ''), ( 'Upper', ''), ( 'Lower', ''), ( 'Signal', '')], names=['Price', 'Ticker'])
Is that expected? Does it shows the same in the cloud and in your local environment?