multiticker / data_updater.py
Jitendra12421's picture
Upload 6 files
69f5fb0 verified
Raw
History Blame Contribute Delete
4.28 kB
import os
import time
import requests
import pandas as pd
from datetime import datetime, date, timedelta
from zoneinfo import ZoneInfo
import pandas_market_calendars as mcal
IST = ZoneInfo("Asia/Kolkata")
DATA_FILE = os.path.join(os.path.dirname(__file__), "data", "nifty50_daily.parquet")
TICKERS = [
'ADANIENT', 'ADANIPORTS', 'APOLLOHOSP', 'ASIANPAINT', 'AXISBANK', 'BAJAJ-AUTO', 'BAJAJFINSV', 'BAJFINANCE',
'BHARTIARTL', 'BPCL', 'BRITANNIA', 'CIPLA', 'COALINDIA', 'DIVISLAB', 'DRREDDY', 'EICHERMOT', 'GRASIM',
'HCLTECH', 'HDFCBANK', 'HDFCLIFE', 'HEROMOTOCO', 'HINDALCO', 'HINDUNILVR', 'ICICIBANK', 'INDUSINDBK',
'INFY', 'ITC', 'JSWSTEEL', 'KOTAKBANK', 'LT', 'M&M', 'MARUTI', 'NESTLEIND', 'NTPC', 'ONGC', 'POWERGRID',
'RELIANCE', 'SBILIFE', 'SBIN', 'SUNPHARMA', 'TATACONSUM', 'TATAMOTORS', 'TATASTEEL', 'TCS', 'TECHM',
'TITAN', 'ULTRACEMCO', 'UPL', 'WIPRO'
]
def is_trading_day(target_date: date) -> bool:
try:
nse = mcal.get_calendar('NSE')
schedule = nse.schedule(start_date=target_date, end_date=target_date)
return not schedule.empty
except Exception as e:
print(f"Calendar check failed: {e}")
# Fallback: assume Monday-Friday is trading day
return target_date.weekday() < 5
def fetch_groww_data(ticker: str, start_ts: int, end_ts: int):
url = f"https://groww.in/v1/api/charting_service/v2/chart/exchange/NSE/segment/CASH/{ticker}?endTimeInMillis={end_ts}&intervalInMinutes=1&startTimeInMillis={start_ts}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Accept": "application/json"
}
try:
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
data = response.json()
if data and 'candles' in data and len(data['candles']) > 0:
# Candles format: [timestamp, open, high, low, close, volume]
last_candle = data['candles'][-1]
return last_candle[4] # Close price
return None
except Exception as e:
print(f"Error fetching {ticker}: {e}")
return None
def update_daily_data():
now = datetime.now(IST)
today = now.date()
if not is_trading_day(today):
print(f"{today} is not a trading day. Skipping update.")
return {"status": "skipped", "reason": "not a trading day"}
if not os.path.exists(DATA_FILE):
print(f"Data file {DATA_FILE} not found!")
return {"status": "error", "reason": "data file missing"}
# Read existing data
df = pd.read_parquet(DATA_FILE)
# Check if we already updated today
if not df.empty and pd.to_datetime(today) in df['date'].dt.date.values:
# We might have partial data or want to overwrite, but for safety:
# Let's delete today's entries if they exist so we can cleanly append
df = df[df['date'].dt.date != today]
print(f"Fetching data for {today}...")
# Market hours: 09:15 to 15:30 IST
start_dt = datetime.combine(today, datetime.strptime("09:15", "%H:%M").time()).replace(tzinfo=IST)
end_dt = datetime.combine(today, datetime.strptime("15:30", "%H:%M").time()).replace(tzinfo=IST)
start_ts = int(start_dt.timestamp() * 1000)
end_ts = int(end_dt.timestamp() * 1000)
new_rows = []
for ticker in TICKERS:
close_price = fetch_groww_data(ticker, start_ts, end_ts)
if close_price is not None:
new_rows.append({
'date': pd.to_datetime(today),
'close': float(close_price),
'ticker': ticker
})
time.sleep(0.5) # Rate limiting
if new_rows:
new_df = pd.DataFrame(new_rows)
updated_df = pd.concat([df, new_df], ignore_index=True)
updated_df.sort_values(by=['ticker', 'date'], inplace=True)
updated_df.to_parquet(DATA_FILE)
print(f"Successfully updated {len(new_rows)} tickers for {today}")
return {"status": "success", "updated_count": len(new_rows)}
else:
print("No new data fetched.")
return {"status": "error", "reason": "fetch failed for all tickers"}
if __name__ == "__main__":
update_daily_data()