import yfinance as yf
import pandas as pd
import datetime
# Stock symbols to screen
NIFTY_STOCKS = [
"[Link]", "[Link]", "[Link]", "[Link]", "[Link]",
"[Link]", "[Link]", "[Link]", "[Link]", "[Link]"
]
BENCHMARK = "^NSEI"
LOOKBACK_DAYS = 20
RV_THRESHOLD = 1.0
def fetch_close_prices(symbol):
df = [Link](symbol, period="30d", interval="1d", progress=False)
if [Link] or 'Close' not in [Link]:
raise ValueError(f"No close price data for {symbol}")
return df['Close'].dropna()
def calculate_volatility(series):
returns = series.pct_change().dropna()
if len(returns) < LOOKBACK_DAYS:
raise ValueError("Not enough return data to calculate volatility")
return float(returns[-LOOKBACK_DAYS:].std())
def calculate_rv(stock_vol, benchmark_vol):
if stock_vol is None or benchmark_vol is None or benchmark_vol == 0:
return None
return float(stock_vol) / float(benchmark_vol)
def run_screener():
print(f"\n🔄 Running Screener @ {[Link]().strftime('%Y-%m-%d %H:
%M:%S')}")
try:
benchmark_prices = fetch_close_prices(BENCHMARK)
benchmark_vol = calculate_volatility(benchmark_prices)
except Exception as e:
print(f"❌ Benchmark error: {e}")
return
results = []
for symbol in NIFTY_STOCKS:
try:
stock_prices = fetch_close_prices(symbol)
stock_vol = calculate_volatility(stock_prices)
rv = calculate_rv(stock_vol, benchmark_vol)
# Ensure RV is a scalar float
if isinstance(rv, float) and rv > RV_THRESHOLD:
[Link]({
"Symbol": symbol,
"Volatility": round(stock_vol, 5),
"RV": round(rv, 3)
})
except Exception as e:
print(f"⚠️ Skipping {symbol}: {e}")
if results:
df = [Link](results).sort_values(by="RV", ascending=False)
print("\n📊 Top Stocks with RV > 1:\n")
print(df.to_string(index=False))
else:
print("⚠️ No stocks with RV above threshold.")
# Run once
run_screener()