File size: 6,922 Bytes
eb606e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Dict, Any, Optional
from app.services.data_fetcher import MutualFundDataFetcher
from app.services.sip_calculator import SIPCalculator
from app.models.fund_models import (
    FundNAVResponse, FundAnalysisRequest, FundAnalysisResponse
)
from app.models.goal_models import (
    SIPCalculationRequest, SIPCalculationResponse,
    RequiredSIPRequest, RequiredSIPResponse
)

# Popular mutual fund categories with scheme codes
POPULAR_FUNDS = {
    'Large Cap Equity': {
        'HDFC Top 100 Fund': '120503',
        'ICICI Pru Bluechip Fund': '120505', 
        'SBI Bluechip Fund': '125497',
        'Axis Bluechip Fund': '120503',
        'Kotak Bluechip Fund': '118989'
    },
    'Mid Cap Equity': {
        'HDFC Mid-Cap Opportunities Fund': '118551',
        'ICICI Pru Mid Cap Fund': '120544',
        'Kotak Emerging Equity Fund': '118999',
        'SBI Magnum Mid Cap Fund': '100281',
        'DSP Mid Cap Fund': '112618'
    },
    'Small Cap Equity': {
        'SBI Small Cap Fund': '122639',
        'DSP Small Cap Fund': '112618',
        'HDFC Small Cap Fund': '118551',
        'Axis Small Cap Fund': '125487',
        'Kotak Small Cap Fund': '119028'
    },
    'ELSS (Tax Saving)': {
        'Axis Long Term Equity Fund': '125494',
        'HDFC Tax Saver': '100277',
        'SBI Tax Saver': '125497',
        'ICICI Pru ELSS Tax Saver': '120503',
        'Kotak Tax Saver': '118989'
    },
    'Debt Funds': {
        'HDFC Corporate Bond Fund': '101762',
        'ICICI Pru Corporate Bond Fund': '120503',
        'SBI Corporate Bond Fund': '125497',
        'Kotak Corporate Bond Fund': '118989',
        'Axis Corporate Debt Fund': '125494'
    },
    'Hybrid Funds': {
        'HDFC Hybrid Equity Fund': '118551',
        'ICICI Pru Balanced Advantage Fund': '120505',
        'SBI Equity Hybrid Fund': '125497',
        'Kotak Equity Hybrid Fund': '118999',
        'Axis Hybrid Fund': '125494'
    }
}

router = APIRouter()

@router.get("/schemes")
async def get_all_schemes():
    """

    Get all available mutual fund schemes

    """
    try:
        fetcher = MutualFundDataFetcher()
        schemes = fetcher.get_all_schemes()
        return {"schemes": schemes}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error fetching schemes: {str(e)}")

@router.get("/nav/{scheme_code}", response_model=FundNAVResponse)
async def get_fund_nav_history(scheme_code: str):
    """

    Get NAV history for a specific mutual fund scheme

    """
    try:
        fetcher = MutualFundDataFetcher()
        nav_data, fund_meta = fetcher.get_fund_nav_history(scheme_code)
        
        return FundNAVResponse(
            meta=fund_meta,
            data=nav_data.to_dict('records')
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error fetching NAV data: {str(e)}")

@router.get("/popular")
async def get_popular_funds():
    """

    Get list of popular mutual funds by category

    """
    return POPULAR_FUNDS

@router.post("/sip-calculate", response_model=SIPCalculationResponse)
async def calculate_sip(request: SIPCalculationRequest, 

                        include_yearly_breakdown: bool = Query(False, description="Include yearly breakdown in response")):
    """

    Calculate SIP maturity amount based on monthly investment, expected return, and time period

    """
    try:
        calculator = SIPCalculator()
        result = calculator.get_sip_calculation(request, include_yearly_breakdown)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error calculating SIP: {str(e)}")

@router.post("/required-sip", response_model=RequiredSIPResponse)
async def calculate_required_sip(request: RequiredSIPRequest):
    """

    Calculate required SIP amount to reach a target amount

    """
    try:
        calculator = SIPCalculator()
        result = calculator.get_required_sip(request)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error calculating required SIP: {str(e)}")

@router.post("/analyze", response_model=FundAnalysisResponse)
async def analyze_funds(request: FundAnalysisRequest):
    """

    Analyze performance of selected mutual funds over a specified period

    """
    try:
        fetcher = MutualFundDataFetcher()
        calculator = SIPCalculator()
        
        analysis_results = []
        
        for fund_name in request.fund_names:
            # Find scheme code for the fund
            scheme_code = None
            fund_category = None
            
            for category, funds in POPULAR_FUNDS.items():
                if fund_name in funds:
                    scheme_code = funds[fund_name]
                    fund_category = category
                    break
            
            if not scheme_code:
                continue
                
            # Fetch NAV data
            nav_data, fund_meta = fetcher.get_fund_nav_history(scheme_code)
            
            if not nav_data.empty:
                returns_data = calculator.calculate_fund_returns(
                    nav_data, request.investment_amount, request.start_date, request.end_date
                )
                
                if returns_data:
                    analysis_results.append({
                        'fund_name': fund_name,
                        'category': fund_category,
                        'scheme_code': scheme_code,
                        'fund_house': fund_meta.fund_house,
                        'returns_data': returns_data,
                        'nav_data': nav_data.to_dict('records'),
                        'fund_meta': fund_meta.dict()
                    })
        
        # Prepare comparison data
        comparison_data = []
        for result in analysis_results:
            returns = result['returns_data']
            comparison_data.append({
                'Fund Name': result['fund_name'],
                'Category': result['category'],
                'Fund House': result['fund_house'],
                'Investment': f"₹{returns['investment_amount']:,.0f}",
                'Current Value': f"₹{returns['final_value']:,.0f}",
                'Total Return': f"{returns['total_return']:.2f}%",
                'Absolute Gain': f"₹{returns['final_value'] - returns['investment_amount']:,.0f}"
            })
        
        return FundAnalysisResponse(
            results=analysis_results,
            comparison_data=comparison_data
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error analyzing funds: {str(e)}")