Spaces:
Running
Running
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)}") |