Squashed 'utils_v2/' content from commit f03179d
git-subtree-dir: utils_v2 git-subtree-split: f03179d339e69fdcdff2f0cc06e1f352024c55d3
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
"""
|
||||
|
||||
AUTHOR:
|
||||
|
||||
Khushal P Soonderji
|
||||
|
||||
DATE:
|
||||
|
||||
Thursday, 28th Nov., 2024
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
To provide a way to retrieve dates of important events like financial-results, stock-splits, fund-raising, etc.
|
||||
from NSE's portal.
|
||||
|
||||
NOTE: This method involves web scraping. It is good for proof-of-concept development, but it is recommended that
|
||||
more professional data-sources be used when the product starts becoming mature.
|
||||
|
||||
REFERENCES:
|
||||
|
||||
N/A
|
||||
|
||||
DOWNLOADS:
|
||||
|
||||
N/A
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** IMPORT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# To make sibling directories accessible for imports:
|
||||
import sys
|
||||
sys.path.append(".")
|
||||
sys.path.append("..")
|
||||
|
||||
# System-level activities:
|
||||
import io
|
||||
|
||||
# My utils:
|
||||
from utils_v2.string import json
|
||||
from utils_v2.date_time import date_time
|
||||
|
||||
# NSE-related utils:
|
||||
from utils_v2.nse.controllers.base import AsyncNSEBase
|
||||
from utils_v2.nse.models.api_call import NSEApiResponse
|
||||
|
||||
# data models:
|
||||
from utils_v2.nse.models.calendar import NSECorporateAction
|
||||
|
||||
# To make REST-ful API calls:
|
||||
import httpx
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
import pytz
|
||||
|
||||
# To work with datatypes:
|
||||
from typing import Any, List
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MACROS / ONE-TIME INIT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** VARIABLES ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** FUNCTIONS ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
class NSECorporateActionsCalendar(AsyncNSEBase):
|
||||
|
||||
# The types of corporate actions/entities:
|
||||
KIND_EQUITIES = "equities"
|
||||
KIND_MUTUAL_FUNDS = "mf"
|
||||
KIND_DEBT = "debt"
|
||||
KIND_SME = "sme"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
http_client: httpx.AsyncClient = None,
|
||||
cookies_refresh_interval: int | float = 300,
|
||||
debug = True,
|
||||
debug_prefix = "NSE (C.Act.) | ",
|
||||
debug_only_errors = True
|
||||
):
|
||||
|
||||
# Pass on the initialization to the parent:
|
||||
super().__init__(
|
||||
base_url = r"https://www.nseindia.com/companies-listing/corporate-filings-actions",
|
||||
data_url = r"https://www.nseindia.com/api/corporates-corporateActions",
|
||||
http_client = http_client,
|
||||
cookies_refresh_interval = cookies_refresh_interval,
|
||||
debug = debug,
|
||||
debug_prefix = debug_prefix,
|
||||
debug_only_errors = debug_only_errors
|
||||
)
|
||||
|
||||
async def get_data(
|
||||
self,
|
||||
kind: str = KIND_EQUITIES,
|
||||
from_date: datetime.datetime = None,
|
||||
to_date: datetime.datetime = None,
|
||||
return_raw: bool = False,
|
||||
refresh_cookies: bool = True,
|
||||
force_refresh_cookies: bool = False,
|
||||
retry_count: int = 1,
|
||||
backoff_seconds: int | float = 0.5,
|
||||
backoff_multiplier: float = 1.1
|
||||
) -> NSEApiResponse:
|
||||
|
||||
"""
|
||||
To get the data of the corporate event calendar.
|
||||
:param kind: The option between 'equities", "mf", "debt", and "sme".
|
||||
:param from_date: The starting date (inclusive) from which the events must be fetched.
|
||||
:param to_date: The ending date (inclusive) till which the events must be fetched.
|
||||
:param return_raw: Whether you want the raw JSON from NSE or you want it formatted.
|
||||
:param refresh_cookies: Whether, or not, you would like to refresh the cookies.
|
||||
:param force_refresh_cookies: If set to True, cookies will be refreshed even if not timed out. If set to False,
|
||||
cookies will be refreshed only when the interval passed to the constructor has elapsed since the last
|
||||
successful refresh.
|
||||
:param retry_count: The no. of times to try to get the data from the API.
|
||||
:param backoff_seconds: The delay between unsuccessful API calls.
|
||||
:param backoff_multiplier: The multiplier to add to the delay to change delay.
|
||||
:return: The raw or formatted event calendar data in the 'data' field of the response model.
|
||||
"""
|
||||
|
||||
# Prepare the inputs:
|
||||
now = date_time.get_current_utc_date_time(as_string = False)
|
||||
from_date = date_time.to_timezone(from_date or now, timezone = date_time.TIMEZONE_IST).strftime("%d-%m-%Y")
|
||||
to_date = date_time.to_timezone(to_date or now, timezone = date_time.TIMEZONE_IST).strftime("%d-%m-%Y")
|
||||
|
||||
# Make the API call:
|
||||
api_response = await self.get(
|
||||
params = {
|
||||
"index": kind,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
},
|
||||
refresh_cookies = refresh_cookies,
|
||||
force_refresh_cookies = force_refresh_cookies,
|
||||
retry_count = retry_count,
|
||||
backoff_seconds = backoff_seconds,
|
||||
backoff_multiplier = backoff_multiplier
|
||||
)
|
||||
|
||||
# If the API call was successful:
|
||||
if api_response.httpCode in [200]:
|
||||
api_response.success = True
|
||||
if return_raw: api_response.data = await api_response.get_json()
|
||||
else:
|
||||
try: api_response.data = self.format_data(
|
||||
raw_json = await api_response.get_json(),
|
||||
kind = kind,
|
||||
timestamp = date_time.get_current_utc_date_time(as_string = True),
|
||||
raise_exception = True
|
||||
)
|
||||
except Exception as exception:
|
||||
api_response.exception = exception
|
||||
api_response.success = False
|
||||
|
||||
# Done here:
|
||||
return api_response
|
||||
|
||||
def format_data(
|
||||
self,
|
||||
raw_json: List[dict],
|
||||
kind: str = None,
|
||||
timestamp: datetime.datetime = None,
|
||||
raise_exception: bool = False
|
||||
) -> List[NSECorporateAction] | None:
|
||||
|
||||
"""
|
||||
We format the data here to be able to retrieve it properly later.
|
||||
:param raw_json: The raw data as scraped from NSE.
|
||||
:param kind: The kind of data pulled using the 'get_data' method.
|
||||
:param timestamp: The timestamp at which the data was scraped. This shall be useful for data retrieval from the
|
||||
database, later.
|
||||
:param raise_exception: If set to True, any exception will be propagated. If set to False, any exception will be
|
||||
suppressed internally.
|
||||
:return: The formatted data if successful, else None.
|
||||
"""
|
||||
|
||||
# Can't do anything if the chain itself is null:
|
||||
if raw_json is None: return []
|
||||
if not isinstance(raw_json, list): return []
|
||||
|
||||
# Start by assuming failure:
|
||||
formatted_data = None
|
||||
|
||||
# Ensure that we've got a proper timestamp:
|
||||
if timestamp is None: timestamp = date_time.get_current_utc_date_time(as_string = False)
|
||||
|
||||
try:
|
||||
|
||||
# Format the data:
|
||||
formatted_data = []
|
||||
for action in raw_json:
|
||||
formatted_data.append(NSECorporateAction(**{
|
||||
"scrapeTs": timestamp,
|
||||
"kind": kind,
|
||||
"symbol": action["symbol"],
|
||||
"name": action["comp"],
|
||||
"isin": action["isin"],
|
||||
"series": action["series"],
|
||||
"ind": action["ind"],
|
||||
"faceVal": float(action["faceVal"]),
|
||||
"action": action["subject"],
|
||||
"exTs": self.parse_datetime_string(action["exDate"], ["%d-%b-%Y"]),
|
||||
"recTs": self.parse_datetime_string(action["recDate"]),
|
||||
"bcStartTs": self.parse_datetime_string(action["bcStartDate"]),
|
||||
"bcEndTs": self.parse_datetime_string(action["bcEndDate"]),
|
||||
"ndStartTs": self.parse_datetime_string(action["ndStartDate"]),
|
||||
"ndEndTs": self.parse_datetime_string(action["ndEndDate"]),
|
||||
"caBroadcastTs": self.parse_datetime_string(action["caBroadcastDate"])
|
||||
}))
|
||||
|
||||
# If something goes wrong:
|
||||
except Exception as exception:
|
||||
formatted_data = None
|
||||
if raise_exception: raise
|
||||
|
||||
# Done here:
|
||||
return formatted_data
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MAIN PROGRAM ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
async def main():
|
||||
|
||||
# Create an instance of the scraper, and refresh its cookies:
|
||||
my_nse = NSECorporateActionsCalendar()
|
||||
|
||||
# Get and show the data:
|
||||
now = date_time.get_current_ist_date_time()
|
||||
to_date = now + datetime.timedelta(days = 31)
|
||||
from_date = now - datetime.timedelta(days = 31)
|
||||
print("FROM :", from_date)
|
||||
print("TO :", to_date)
|
||||
api_response = await my_nse.get_data(
|
||||
kind = NSECorporateActionsCalendar.KIND_DEBT,
|
||||
from_date = from_date,
|
||||
to_date = to_date,
|
||||
return_raw = False
|
||||
)
|
||||
print("SUMMARY:", api_response.to_markdown(), "\n---\n\n")
|
||||
if api_response.success: print("CORPORATE ACTIONS:", json.to_string(api_response.data, default = str))
|
||||
else: raise api_response.exception
|
||||
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,273 @@
|
||||
"""
|
||||
|
||||
AUTHOR:
|
||||
|
||||
Khushal P Soonderji
|
||||
|
||||
DATE:
|
||||
|
||||
Thursday, 28th Nov., 2024
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
To provide a way to retrieve dates of important events like financial-results, stock-splits, fund-raising, etc.
|
||||
from NSE's portal.
|
||||
|
||||
NOTE: This method involves web scraping. It is good for proof-of-concept development, but it is recommended that
|
||||
more professional data-sources be used when the product starts becoming mature.
|
||||
|
||||
REFERENCES:
|
||||
|
||||
N/A
|
||||
|
||||
DOWNLOADS:
|
||||
|
||||
N/A
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** IMPORT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# To make sibling directories accessible for imports:
|
||||
import sys
|
||||
sys.path.append(".")
|
||||
sys.path.append("..")
|
||||
|
||||
# System-level activities:
|
||||
import io
|
||||
|
||||
# My utils:
|
||||
from utils_v2.string import json
|
||||
from utils_v2.date_time import date_time
|
||||
|
||||
# NSE-related utils:
|
||||
from utils_v2.nse.controllers.base import AsyncNSEBase
|
||||
from utils_v2.nse.models.api_call import NSEApiResponse
|
||||
|
||||
# Data models:
|
||||
from utils_v2.nse.models.calendar import NSECorporateEvent
|
||||
|
||||
# To make REST-ful API calls:
|
||||
import httpx
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
|
||||
# To work with datatypes:
|
||||
from typing import Any, List
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MACROS / ONE-TIME INIT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** VARIABLES ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** FUNCTIONS ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
class NSECorporateEventsCalendar(AsyncNSEBase):
|
||||
|
||||
# Index types:
|
||||
KIND_EQUITIES = "equities"
|
||||
KIND_SME = "sme"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
http_client: httpx.AsyncClient = None,
|
||||
cookies_refresh_interval: int | float = 300,
|
||||
debug = True,
|
||||
debug_prefix = "NSE (CECal) | ",
|
||||
debug_only_errors = True
|
||||
):
|
||||
|
||||
# Pass on the initialization to the parent:
|
||||
super().__init__(
|
||||
base_url = r"https://www.nseindia.com/companies-listing/corporate-filings-event-calendar",
|
||||
data_url = r"https://www.nseindia.com/api/event-calendar",
|
||||
http_client = http_client,
|
||||
cookies_refresh_interval = cookies_refresh_interval,
|
||||
debug = debug,
|
||||
debug_prefix = debug_prefix,
|
||||
debug_only_errors = debug_only_errors
|
||||
)
|
||||
|
||||
async def get_data(
|
||||
self,
|
||||
kind: str = KIND_EQUITIES,
|
||||
from_date: datetime.datetime = None,
|
||||
to_date: datetime.datetime = None,
|
||||
return_raw: bool = False,
|
||||
refresh_cookies: bool = True,
|
||||
force_refresh_cookies: bool = False,
|
||||
retry_count: int = 1,
|
||||
backoff_seconds: int | float = 0.5,
|
||||
backoff_multiplier: float = 1.1
|
||||
) -> NSEApiResponse:
|
||||
|
||||
"""
|
||||
To get the data of the corporate event calendar.
|
||||
:param kind: The type of index you want. A choice between "equities" and "sme"
|
||||
:param from_date: The starting date (inclusive) from which the events must be fetched.
|
||||
:param to_date: The ending date (inclusive) till which the events must be fetched.
|
||||
:param return_raw: Whether you want the raw JSON from NSE or you want it formatted.
|
||||
:param refresh_cookies: Whether, or not, you would like to refresh the cookies.
|
||||
:param force_refresh_cookies: If set to True, cookies will be refreshed even if not timed out. If set to False,
|
||||
cookies will be refreshed only when the interval passed to the constructor has elapsed since the last
|
||||
successful refresh.
|
||||
:param retry_count: The no. of times to try to get the data from the API.
|
||||
:param backoff_seconds: The delay between unsuccessful API calls.
|
||||
:param backoff_multiplier: The multiplier to add to the delay to change delay.
|
||||
:return: The raw or formatted event calendar data in the 'data' field of the response model.
|
||||
"""
|
||||
|
||||
# Prepare the inputs:
|
||||
now = date_time.get_current_utc_date_time(as_string = False)
|
||||
from_date = date_time.to_timezone(from_date or now, timezone = date_time.TIMEZONE_IST).strftime("%d-%m-%Y")
|
||||
to_date = date_time.to_timezone(to_date or now, timezone = date_time.TIMEZONE_IST).strftime("%d-%m-%Y")
|
||||
|
||||
# Make the API call:
|
||||
api_response = await self.get(
|
||||
params = {
|
||||
"index": kind,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date
|
||||
},
|
||||
refresh_cookies = refresh_cookies,
|
||||
force_refresh_cookies = force_refresh_cookies,
|
||||
retry_count = retry_count,
|
||||
backoff_seconds = backoff_seconds,
|
||||
backoff_multiplier = backoff_multiplier
|
||||
)
|
||||
|
||||
# If the API call was successful:
|
||||
if api_response.httpCode in [200]:
|
||||
api_response.success = True
|
||||
if return_raw: api_response.data = await api_response.get_json()
|
||||
else:
|
||||
try: api_response.data = self.format_data(
|
||||
raw_json = await api_response.get_json(),
|
||||
kind = kind,
|
||||
timestamp = date_time.get_current_utc_date_time(as_string = False),
|
||||
raise_exception = True
|
||||
)
|
||||
except Exception as exception:
|
||||
api_response.exception = exception
|
||||
api_response.success = False
|
||||
|
||||
# Done here:
|
||||
return api_response
|
||||
|
||||
@staticmethod
|
||||
def format_data(
|
||||
raw_json: List[dict],
|
||||
kind: str = None,
|
||||
timestamp: datetime.datetime = None,
|
||||
raise_exception: bool = False
|
||||
) -> List[NSECorporateEvent] | None:
|
||||
|
||||
"""
|
||||
We format the data here to be able to retrieve it properly later.
|
||||
:param raw_json: The raw data as scraped from NSE.
|
||||
:param kind: The kind of data pulled using the 'get_data' method.
|
||||
:param timestamp: The timestamp at which the data was scraped. This shall be useful for data retrieval from the
|
||||
database, later.
|
||||
:param raise_exception: If set to True, any exception will be propagated. If set to False, any exception will be
|
||||
suppressed internally.
|
||||
:return: The formatted data if successful, else None.
|
||||
"""
|
||||
|
||||
# Can't do anything if the chain itself is null:
|
||||
if raw_json is None: return raw_json
|
||||
|
||||
# Start by assuming failure:
|
||||
formatted_data = None
|
||||
|
||||
# Ensure that we've got a proper timestamp:
|
||||
if timestamp is None: timestamp = date_time.get_current_utc_date_time(as_string = False)
|
||||
|
||||
try:
|
||||
|
||||
# Format the data:
|
||||
formatted_data = [
|
||||
{
|
||||
"scrapeTs": timestamp,
|
||||
"kind": kind,
|
||||
"symbol": event.get("symbol", event.get("bm_symbol")),
|
||||
"name": event.get("company", event.get("sm_name")),
|
||||
"ts": date_time.to_timezone(
|
||||
date_time.parse_date_time(
|
||||
event.get("date", event.get("bm_date")),
|
||||
timezone = date_time.TIMEZONE_IST
|
||||
),
|
||||
timezone = date_time.TIMEZONE_UTC
|
||||
),
|
||||
"tz": "Asia/Kolkata",
|
||||
"purpose": event.get("purpose", event.get("bm_purpose")),
|
||||
"description": event.get("bm_desc"),
|
||||
"attachment": event.get("attachment")
|
||||
} for event in raw_json
|
||||
]
|
||||
formatted_data = [NSECorporateEvent(**d) for d in formatted_data]
|
||||
|
||||
# If something goes wrong:
|
||||
except Exception as exception:
|
||||
formatted_data = None
|
||||
if raise_exception: raise
|
||||
|
||||
# Done here:
|
||||
return formatted_data
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MAIN PROGRAM ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
async def main():
|
||||
|
||||
# Create an instance of the scraper, and refresh its cookies:
|
||||
my_nse = NSECorporateEventsCalendar()
|
||||
|
||||
# Get and show the data:
|
||||
api_response = await my_nse.get_data(
|
||||
kind = NSECorporateEventsCalendar.KIND_EQUITIES,
|
||||
from_date = datetime.datetime(year = 2024, month = 1, day = 1),
|
||||
to_date = datetime.datetime(year = 2025, month = 1, day = 1),
|
||||
return_raw = False
|
||||
)
|
||||
print("SUMMARY:", api_response.to_markdown(), "\n---\n\n")
|
||||
if api_response.success: print("CORPORATE EVENT CALENDAR:", json.to_string(api_response.data, default = str))
|
||||
|
||||
asyncio.run(main())
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
[
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "AAREYDRUGS",
|
||||
"company": "Aarey Drugs & Pharmaceuticals Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Fund Raising/Other business matters",
|
||||
"brief": "To consider Fund Raising and other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "ASTERDM",
|
||||
"company": "Aster DM Healthcare Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider other business matters pertaining to Preferential Issue."
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "EROSMEDIA",
|
||||
"company": "Eros International Media Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Financial Results/Other business matters",
|
||||
"brief": "To consider and approve the financial results for the quarter and year ended March 31, 2024 and other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "MUFIN",
|
||||
"company": "Mufin Green Finance Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Fund Raising",
|
||||
"brief": "To consider Fund Raising by Issue of Secured Unlisted Non Convertible Debenture."
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "ONMOBILE",
|
||||
"company": "OnMobile Global Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Fund Raising",
|
||||
"brief": "To consider Fund Raising"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "PRIVISCL",
|
||||
"company": "Privi Speciality Chemicals Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider and Approve \"Privi Employee Stock Option Scheme - 2024\""
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "SOUTHBANK",
|
||||
"company": "The South Indian Bank Limited",
|
||||
"eventDate": "2024-11-28 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider, decide on exercise of call option of Bank s Non-convertible, fully paid-up, unsecured, perpetual, Basel III Compliant, Tier I Bonds, listed in BSE"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "BCG",
|
||||
"company": "Brightcom Group Limited",
|
||||
"eventDate": "2024-11-29 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "BCG",
|
||||
"company": "Brightcom Group Limited",
|
||||
"eventDate": "2024-11-29 18:07:00+00:00",
|
||||
"eventType": "Financial Results",
|
||||
"brief": "To consider and approve the financial results for the period ended Jun 30, 2024"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "SIKKO",
|
||||
"company": "Sikko Industries Limited",
|
||||
"eventDate": "2024-11-29 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider discuss and decide terms and conditions such as determination of the rights issue price, rights entitlement ratio, record date and other matters incidental orconnected therewith."
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "AGIIL",
|
||||
"company": "Agi Infra Limited",
|
||||
"eventDate": "2024-12-01 18:07:00+00:00",
|
||||
"eventType": "Stock Split",
|
||||
"brief": "To consider stock split of equity shares of the Company"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "MANAKCOAT",
|
||||
"company": "Manaksia Coated Metals & Industries Limited",
|
||||
"eventDate": "2024-12-01 18:07:00+00:00",
|
||||
"eventType": "Fund Raising",
|
||||
"brief": "To consider Fund Raising"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "NTL",
|
||||
"company": "Neueon Towers Limited",
|
||||
"eventDate": "2024-12-01 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider the enclosed business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "PAR",
|
||||
"company": "Par Drugs and Chemicals Limited",
|
||||
"eventDate": "2024-12-01 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "FIBERWEB",
|
||||
"company": "Fiberweb (India) Limited",
|
||||
"eventDate": "2024-12-02 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider and discuss about the expansion plans"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "IITL",
|
||||
"company": "Industrial Investment Trust Limited",
|
||||
"eventDate": "2024-12-02 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "SWIGGY",
|
||||
"company": "Swiggy Limited",
|
||||
"eventDate": "2024-12-02 18:07:00+00:00",
|
||||
"eventType": "Financial Results",
|
||||
"brief": "To consider and approve the financial results for the quarter and half year ended September 30, 2024"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "GBGLOBAL",
|
||||
"company": "GB Global Limited",
|
||||
"eventDate": "2024-12-03 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider other business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "MOTOGENFIN",
|
||||
"company": "The Motor & General Finance Limited",
|
||||
"eventDate": "2024-12-03 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "Intimation Regarding Independent Directors Meeting will be held on 04.12.2024."
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "DIL",
|
||||
"company": "Debock Industries Limited",
|
||||
"eventDate": "2024-12-04 18:07:00+00:00",
|
||||
"eventType": "Financial Results",
|
||||
"brief": "DIL : 05-Dec-2024 : The Company has informed the Exchange that a Board meeting to be held on November 27, 2024 has been re-scheduled. Further, the Company has informed the Exchange that the meeting of the Board of Directors of the Company will be held on December 05, 2024, To consider and approve the financial results for the period ended September 30, 2024"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "NTL",
|
||||
"company": "Neueon Towers Limited",
|
||||
"eventDate": "2024-12-08 18:07:00+00:00",
|
||||
"eventType": "Other business matters",
|
||||
"brief": "To consider enclosed business matters"
|
||||
},
|
||||
{
|
||||
"ts": "2024-11-28 15:11:22.793824+05:30",
|
||||
"symbol": "EXIDEIND",
|
||||
"company": "Exide Industries Limited",
|
||||
"eventDate": "2025-01-27 18:07:00+00:00",
|
||||
"eventType": "Financial Results",
|
||||
"brief": "To consider and approve the financial results for the period ended December 31, 2024"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,156 @@
|
||||
[
|
||||
{
|
||||
"symbol": "AAREYDRUGS",
|
||||
"company": "Aarey Drugs & Pharmaceuticals Limited",
|
||||
"purpose": "Fund Raising/Other business matters",
|
||||
"bm_desc": "To consider Fund Raising and other business matters",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "ASTERDM",
|
||||
"company": "Aster DM Healthcare Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider other business matters pertaining to Preferential Issue.",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "EROSMEDIA",
|
||||
"company": "Eros International Media Limited",
|
||||
"purpose": "Financial Results/Other business matters",
|
||||
"bm_desc": "To consider and approve the financial results for the quarter and year ended March 31, 2024 and other business matters",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "MUFIN",
|
||||
"company": "Mufin Green Finance Limited",
|
||||
"purpose": "Fund Raising",
|
||||
"bm_desc": "To consider Fund Raising by Issue of Secured Unlisted Non Convertible Debenture.",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "ONMOBILE",
|
||||
"company": "OnMobile Global Limited",
|
||||
"purpose": "Fund Raising",
|
||||
"bm_desc": "To consider Fund Raising",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "PRIVISCL",
|
||||
"company": "Privi Speciality Chemicals Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider and Approve \"Privi Employee Stock Option Scheme - 2024\"",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "SOUTHBANK",
|
||||
"company": "The South Indian Bank Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider, decide on exercise of call option of Bank s Non-convertible, fully paid-up, unsecured, perpetual, Basel III Compliant, Tier I Bonds, listed in BSE",
|
||||
"date": "29-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "BCG",
|
||||
"company": "Brightcom Group Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider other business matters",
|
||||
"date": "30-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "BCG",
|
||||
"company": "Brightcom Group Limited",
|
||||
"purpose": "Financial Results",
|
||||
"bm_desc": "To consider and approve the financial results for the period ended Jun 30, 2024",
|
||||
"date": "30-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "SIKKO",
|
||||
"company": "Sikko Industries Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider discuss and decide terms and conditions such as determination of the rights issue price, rights entitlement ratio, record date and other matters incidental orconnected therewith.",
|
||||
"date": "30-Nov-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "AGIIL",
|
||||
"company": "Agi Infra Limited",
|
||||
"purpose": "Stock Split",
|
||||
"bm_desc": "To consider stock split of equity shares of the Company",
|
||||
"date": "02-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "MANAKCOAT",
|
||||
"company": "Manaksia Coated Metals & Industries Limited",
|
||||
"purpose": "Fund Raising",
|
||||
"bm_desc": "To consider Fund Raising",
|
||||
"date": "02-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "NTL",
|
||||
"company": "Neueon Towers Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider the enclosed business matters",
|
||||
"date": "02-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "PAR",
|
||||
"company": "Par Drugs and Chemicals Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider other business matters",
|
||||
"date": "02-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "FIBERWEB",
|
||||
"company": "Fiberweb (India) Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider and discuss about the expansion plans",
|
||||
"date": "03-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "IITL",
|
||||
"company": "Industrial Investment Trust Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider other business matters",
|
||||
"date": "03-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "SWIGGY",
|
||||
"company": "Swiggy Limited",
|
||||
"purpose": "Financial Results",
|
||||
"bm_desc": "To consider and approve the financial results for the quarter and half year ended September 30, 2024",
|
||||
"date": "03-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "GBGLOBAL",
|
||||
"company": "GB Global Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider other business matters",
|
||||
"date": "04-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "MOTOGENFIN",
|
||||
"company": "The Motor & General Finance Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "Intimation Regarding Independent Directors Meeting will be held on 04.12.2024.",
|
||||
"date": "04-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "DIL",
|
||||
"company": "Debock Industries Limited",
|
||||
"purpose": "Financial Results",
|
||||
"bm_desc": "DIL : 05-Dec-2024 : The Company has informed the Exchange that a Board meeting to be held on November 27, 2024 has been re-scheduled. Further, the Company has informed the Exchange that the meeting of the Board of Directors of the Company will be held on December 05, 2024, To consider and approve the financial results for the period ended September 30, 2024",
|
||||
"date": "05-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "NTL",
|
||||
"company": "Neueon Towers Limited",
|
||||
"purpose": "Other business matters",
|
||||
"bm_desc": "To consider enclosed business matters",
|
||||
"date": "09-Dec-2024"
|
||||
},
|
||||
{
|
||||
"symbol": "EXIDEIND",
|
||||
"company": "Exide Industries Limited",
|
||||
"purpose": "Financial Results",
|
||||
"bm_desc": "To consider and approve the financial results for the period ended December 31, 2024",
|
||||
"date": "28-Jan-2025"
|
||||
}
|
||||
]
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
[
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-01-21 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Special Holiday",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-01-25 18:30:00+00:00",
|
||||
"weekDay": "Friday",
|
||||
"event": "Republic Day",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-02-18 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Chatrapati Shivaji Maharaj Jayanti",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"IRD",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-03-07 18:30:00+00:00",
|
||||
"weekDay": "Friday",
|
||||
"event": "Mahashivratri",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-03-24 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Holi",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-03-28 18:30:00+00:00",
|
||||
"weekDay": "Friday",
|
||||
"event": "Good Friday",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-03-31 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Annual Bank Closing",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"IRD",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-08 18:30:00+00:00",
|
||||
"weekDay": "Tuesday",
|
||||
"event": "Gudi Padwa",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"IRD",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-10 18:30:00+00:00",
|
||||
"weekDay": "Thursday",
|
||||
"event": "Id-Ul-Fitr (Ramadan Id)",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-13 18:30:00+00:00",
|
||||
"weekDay": "Sunday",
|
||||
"event": "Dr.Baba Saheb Ambedkar Jayanti",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-16 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Shri Ram Navami",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-20 18:30:00+00:00",
|
||||
"weekDay": "Sunday",
|
||||
"event": "Mahavir Jayanti",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-04-30 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Maharashtra Day",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-05-19 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "General Parliamentary Elections",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-05-22 18:30:00+00:00",
|
||||
"weekDay": "Thursday",
|
||||
"event": "Buddha Pournima",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"IRD",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-06-16 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Bakri Id",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-07-16 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Muharram",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-08-14 18:30:00+00:00",
|
||||
"weekDay": "Thursday",
|
||||
"event": "Independence Day/Parsi New Year",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-09-06 18:30:00+00:00",
|
||||
"weekDay": "Saturday",
|
||||
"event": "Ganesh Chaturthi",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-09-15 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "Id-E-Milad",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"IRD",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-10-01 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Mahatma Gandhi Jayanti",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-10-11 18:30:00+00:00",
|
||||
"weekDay": "Saturday",
|
||||
"event": "Dussehra",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-11-01 18:30:00+00:00",
|
||||
"weekDay": "Saturday",
|
||||
"event": "Balipratipada",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-11-14 18:30:00+00:00",
|
||||
"weekDay": "Friday",
|
||||
"event": "Prakash Gurpurb Sri Guru Nanak Dev",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-11-19 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Assembly Elections in Maharashtra",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-12-24 18:30:00+00:00",
|
||||
"weekDay": "Wednesday",
|
||||
"event": "Christmas",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"CBM",
|
||||
"CD",
|
||||
"CM",
|
||||
"CMOT",
|
||||
"COM",
|
||||
"FO",
|
||||
"IRD",
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP",
|
||||
"SLBS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2023-12-31 18:30:00+00:00",
|
||||
"weekDay": "Monday",
|
||||
"event": "New year",
|
||||
"morningSession": "Open",
|
||||
"eveningSession": "Closed",
|
||||
"holidayType": [
|
||||
"COM"
|
||||
]
|
||||
},
|
||||
{
|
||||
"scrapeTs": "2024-12-05T04:19:17.317730+00:00",
|
||||
"date": "2024-10-31 18:30:00+00:00",
|
||||
"weekDay": "Friday",
|
||||
"event": "Diwali Laxmi Pujan",
|
||||
"morningSession": null,
|
||||
"eveningSession": null,
|
||||
"holidayType": [
|
||||
"MF",
|
||||
"NDM",
|
||||
"NTRP"
|
||||
]
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,323 @@
|
||||
"""
|
||||
|
||||
AUTHOR:
|
||||
|
||||
Khushal P Soonderji
|
||||
|
||||
DATE:
|
||||
|
||||
Thursday, 5th Dec., 2024
|
||||
|
||||
OBJECTIVE:
|
||||
|
||||
To provide a way to retrieve the list of holidays from NSE and to check if today is a holiday.
|
||||
|
||||
NOTE: This method involves web scraping. It is good for proof-of-concept development, but it is recommended that
|
||||
more professional data-sources be used when the product starts becoming mature.
|
||||
|
||||
REFERENCES:
|
||||
|
||||
N/A
|
||||
|
||||
DOWNLOADS:
|
||||
|
||||
N/A
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** IMPORT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# To make sibling directories accessible for imports:
|
||||
import sys
|
||||
sys.path.append(".")
|
||||
sys.path.append("..")
|
||||
|
||||
# System-level activities:
|
||||
import io
|
||||
|
||||
# My utils:
|
||||
from utils_v2.string import json
|
||||
from utils_v2.date_time import date_time
|
||||
|
||||
# NSE-related utils:
|
||||
from utils_v2.nse.controllers.base import AsyncNSEBase
|
||||
from utils_v2.nse.models.api_call import NSEApiResponse
|
||||
|
||||
# Data models:
|
||||
from utils_v2.nse.models.calendar import NSEHoliday
|
||||
|
||||
# To make REST-ful API calls:
|
||||
import httpx
|
||||
|
||||
# To work with date and time:
|
||||
import datetime
|
||||
|
||||
# To work with datatypes:
|
||||
from typing import Any, List
|
||||
|
||||
# For asynchronous activities:
|
||||
import asyncio
|
||||
|
||||
# For debugging:
|
||||
import inspect
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MACROS / ONE-TIME INIT ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** VARIABLES ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
# --- Nothing Yet
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** FUNCTIONS ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
class NSEHolidaysCalendar(AsyncNSEBase):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
http_client: httpx.AsyncClient = None,
|
||||
cookies_refresh_interval: int | float = 300,
|
||||
debug = True,
|
||||
debug_prefix = "NSE (Hol) | ",
|
||||
debug_only_errors = True
|
||||
):
|
||||
|
||||
# Pass on the initialization to the parent:
|
||||
super().__init__(
|
||||
base_url = r"https://www.nseindia.com/resources/exchange-communication-holidays",
|
||||
data_url = r"https://www.nseindia.com/api/holiday-master?type=trading",
|
||||
http_client = http_client,
|
||||
cookies_refresh_interval = cookies_refresh_interval,
|
||||
debug = debug,
|
||||
debug_prefix = debug_prefix,
|
||||
debug_only_errors = debug_only_errors
|
||||
)
|
||||
|
||||
async def get_data(
|
||||
self,
|
||||
return_raw: bool = False,
|
||||
refresh_cookies: bool = True,
|
||||
force_refresh_cookies: bool = False,
|
||||
retry_count: int = 1,
|
||||
backoff_seconds: int | float = 0.5,
|
||||
backoff_multiplier: float = 1.1
|
||||
) -> NSEApiResponse:
|
||||
|
||||
"""
|
||||
To get the data of the holiday calendar.
|
||||
:param return_raw: Whether you want the raw JSON from NSE or you want it formatted.
|
||||
:param refresh_cookies: Whether, or not, you would like to refresh the cookies.
|
||||
:param force_refresh_cookies: If set to True, cookies will be refreshed even if not timed out. If set to False,
|
||||
cookies will be refreshed only when the interval passed to the constructor has elapsed since the last
|
||||
successful refresh.
|
||||
:param retry_count: The no. of times to try to get the data from the API.
|
||||
:param backoff_seconds: The delay between unsuccessful API calls.
|
||||
:param backoff_multiplier: The multiplier to add to the delay to change delay.
|
||||
:return: The raw or formatted event calendar data in the 'data' field of the response model.
|
||||
"""
|
||||
|
||||
# Make the API call:
|
||||
api_response = await self.get(
|
||||
refresh_cookies = refresh_cookies,
|
||||
force_refresh_cookies = force_refresh_cookies,
|
||||
retry_count = retry_count,
|
||||
backoff_seconds = backoff_seconds,
|
||||
backoff_multiplier = backoff_multiplier
|
||||
)
|
||||
|
||||
# If the API call was successful:
|
||||
if api_response.httpCode in [200]:
|
||||
api_response.success = True
|
||||
if return_raw: api_response.data = await api_response.get_json()
|
||||
else:
|
||||
try: api_response.data = self.format_data(
|
||||
raw_json = await api_response.get_json(),
|
||||
timestamp = date_time.get_current_utc_date_time(as_string = False),
|
||||
raise_exception = True
|
||||
)
|
||||
except Exception as exception:
|
||||
api_response.exception = exception
|
||||
api_response.success = False
|
||||
|
||||
# Done here:
|
||||
return api_response
|
||||
|
||||
@staticmethod
|
||||
def format_data(
|
||||
raw_json: dict,
|
||||
timestamp: datetime.datetime = None,
|
||||
raise_exception: bool = False
|
||||
) -> List[NSEHoliday] | None:
|
||||
|
||||
"""
|
||||
We format the data here to be able to retrieve it properly later.
|
||||
:param raw_json: The raw data as scraped from NSE.
|
||||
:param timestamp: The timestamp at which the data was scraped. This shall be useful for data retrieval from the
|
||||
database, later.
|
||||
:param raise_exception: If set to True, any exception will be propagated. If set to False, any exception will be
|
||||
suppressed internally.
|
||||
:return: The formatted data if successful, else None.
|
||||
"""
|
||||
|
||||
# Can't do anything if the chain itself is null:
|
||||
if raw_json is None: return raw_json
|
||||
|
||||
# Start by assuming failure:
|
||||
formatted_data = None
|
||||
|
||||
# Ensure that we've got a proper timestamp:
|
||||
if timestamp is None: timestamp = date_time.get_current_utc_date_time(as_string = False)
|
||||
|
||||
try:
|
||||
|
||||
# Start by creating an empty dict:
|
||||
formatted_data = {}
|
||||
|
||||
# Process each category in the original data
|
||||
for category, events in raw_json.items():
|
||||
for event in events:
|
||||
trading_date = event["tradingDate"]
|
||||
|
||||
# If the tradingDate is not in the dictionary, initialize it
|
||||
if trading_date not in formatted_data:
|
||||
formatted_data[trading_date] = {
|
||||
"scrapeTs": timestamp,
|
||||
"ts": date_time.to_timezone(
|
||||
date_time.as_if_timezone(
|
||||
datetime.datetime.strptime(trading_date, "%d-%b-%Y"),
|
||||
timezone = date_time.TIMEZONE_IST
|
||||
),
|
||||
timezone = date_time.TIMEZONE_UTC
|
||||
),
|
||||
"tz": "Asia/Kolkata",
|
||||
"weekday": event["weekDay"],
|
||||
"event": event["description"],
|
||||
"type": []
|
||||
}
|
||||
|
||||
# Add the current category to the "type" list
|
||||
formatted_data[trading_date]["type"].append(category)
|
||||
|
||||
# Now we get rid of the unnecessary keys and make it a list, and model it:
|
||||
formatted_data = [v for v in formatted_data.values()]
|
||||
formatted_data = [NSEHoliday(**d) for d in formatted_data]
|
||||
|
||||
# If something goes wrong:
|
||||
except Exception as exception:
|
||||
formatted_data = None
|
||||
if raise_exception: raise
|
||||
|
||||
# Done here:
|
||||
return formatted_data
|
||||
|
||||
async def is_holiday(
|
||||
self,
|
||||
timestamp: datetime.datetime
|
||||
) -> NSEApiResponse:
|
||||
|
||||
"""
|
||||
Checks if a given date is a trading holiday, or not.
|
||||
:param timestamp: The datetime instance that you want to check for it being a holiday. Preferably make it an
|
||||
aware instance. If a naive instance is passed, it will be assumed to be in UTC.
|
||||
:return: True if it is a holiday, False if it isn't. Can be None if something goes wrong in fetching the data.
|
||||
The value will be in the 'data' field of the response model.
|
||||
"""
|
||||
|
||||
# We first prepare UTC and IST versions of the incoming datetime:
|
||||
timestamp_utc = date_time.to_timezone(timestamp, timezone = date_time.TIMEZONE_UTC)
|
||||
timestamp_ist = date_time.to_timezone(timestamp_utc, timezone = date_time.TIMEZONE_IST)
|
||||
|
||||
# If this day is a weekend, it is a holiday by default:
|
||||
ist_dow = timestamp_ist.weekday()
|
||||
if ist_dow in [5, 6]: return NSEApiResponse(
|
||||
action = inspect.stack()[0].function,
|
||||
url = None,
|
||||
method = None,
|
||||
success = True,
|
||||
data = {
|
||||
"isHoliday": True,
|
||||
"event": "Saturday" if ist_dow == 5 else "Sunday"
|
||||
},
|
||||
message = "Holiday due to weekend."
|
||||
)
|
||||
|
||||
# First we fetch the data from NSE:
|
||||
api_response = await self.get_data(return_raw = False)
|
||||
api_response.action = inspect.stack()[0].function
|
||||
if not api_response.success: return api_response
|
||||
|
||||
# Now we check if our date to check is in the list:
|
||||
is_holiday = False
|
||||
event = None
|
||||
for h in api_response.data:
|
||||
if h.ts.date() == timestamp_utc.date():
|
||||
is_holiday = True
|
||||
event = h.event
|
||||
break
|
||||
api_response.data = {
|
||||
"isHoliday": is_holiday,
|
||||
"event": event
|
||||
}
|
||||
|
||||
# Done here:
|
||||
return api_response
|
||||
|
||||
|
||||
# *****************************************************************************************************************
|
||||
# ***** ****
|
||||
# *** MAIN PROGRAM ***
|
||||
# ***** ****
|
||||
# *****************************************************************************************************************
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
async def main():
|
||||
|
||||
# Create an instance of the scraper, and refresh its cookies:
|
||||
my_nse = NSEHolidaysCalendar()
|
||||
|
||||
# Get and show the data:
|
||||
api_response = await my_nse.get_data(return_raw = False)
|
||||
print("SUMMARY:", api_response.to_markdown(), "\n---\n\n")
|
||||
if api_response.success: print("HOLIDAY CALENDAR:", json.to_string(api_response.data, default = str))
|
||||
ts = api_response.data[0].ts
|
||||
print(ts, type(ts))
|
||||
print("\n---\n\n")
|
||||
|
||||
# # Check for a holiday:
|
||||
# date_to_check = date_time.parse_date_time(
|
||||
# input_value = "2025-12-25 00:00:00",
|
||||
# date_formats = ["%Y-%m-%d %H:%M:%S"],
|
||||
# timezone = date_time.TIMEZONE_IST
|
||||
# )
|
||||
# api_response = await my_nse.is_holiday(date_to_check)
|
||||
# print("SUMMARY:", api_response.to_markdown(), "\n---\n\n")
|
||||
# print("DATETIME:", date_to_check)
|
||||
# print("IS HOLIDAY:", api_response.data)
|
||||
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user