Spaces:
Running
Running
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() | |
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)}") | |
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)}") | |
async def get_popular_funds(): | |
""" | |
Get list of popular mutual funds by category | |
""" | |
return POPULAR_FUNDS | |
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)}") | |
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)}") | |
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)}") |