""" This command is used to fetch all the data relating to mutual funds and save it to the database. """ import logging import time from django.core.management.base import BaseCommand from core.constants import MONEYCONTROL_TOPSTOCKS_URL from core.models import MutualFund from core.clients.mutual_fund import ( MFList, MFQuote, MFHoldings, MFRiskMeasures, MFRanking, ) from core.clients.stock import StockDetails, StockRankings logger = logging.getLogger(__name__) def get_funds_details() -> None: """ Get the details of the top 30 mutual funds and store them in the database. """ t1 = time.perf_counter() mutual_funds = MutualFund.objects.exclude(rank=None).order_by("rank")[:30] logger.info(f"{mutual_funds=}") for mf in mutual_funds: # fetching the quotes data from the morningstar api and storing it in the database MFQuote(mf.isin_number).run() time.sleep(2) # fetching the holdings data from the morningstar api and storing it in the database MFHoldings(mf.isin_number).run() time.sleep(2) # fetching the risk measures data from the morningstar api and storing it in the database MFRiskMeasures(mf.isin_number).run() time.sleep(2) logger.info("Time taken: %s", time.perf_counter() - t1) def get_stock_details() -> None: """ Retrieves stock details for the top 30 mutual funds and updates the database. """ count = 0 t1 = time.perf_counter() mutual_funds = MutualFund.objects.exclude(rank=None).order_by("rank")[:30] for mf in mutual_funds: try: holdings = ( mf.data["holdings"].get("equityHoldingPage", {}).get("holdingList", []) ) except KeyError: logger.warning("KeyError for holdings on Mutual Fund %s", mf.isin_number) for holding in holdings: performance_id = holding.get("performanceId") isin = holding.get("isin") if not performance_id or not isin: logger.warning("Missing performanceId or isin for Mutual Fund %s", isin) MFHoldings(mf.isin_number).run() stock_details = StockDetails(performance_id, isin) stock_details.run() count += 1 logger.info("Processed count: %s", count) logger.info("Time taken by stock details: %s", time.perf_counter() - t1) class Command(BaseCommand): help = "Morningstar API to save the JSON response to a file which contains secIds with other details" def handle(self, *args, **options) -> None: t1 = time.perf_counter() try: # MFList().run() # MFRanking().run() # get_funds_details() StockRankings().run() get_stock_details() except Exception as e: logger.exception(e) self.stdout.write(f"Time taken by: {time.perf_counter() - t1}")