File size: 2,949 Bytes
38171fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29b753f
 
 
38171fa
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
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}")