You can also refer to some more below 
Mutual Fund API (mfapi.in)
Direct API link: https://mfapi.in/
Features:
Free REST API for Indian Mutual Funds
Get historical NAV data
Search schemes by name/code
Example Usage:
pythonCopy# Get NAV for a specific scheme
scheme_code = '119598' # Example: SBI Blue Chip Fund-Direct Plan-Growth
api_url = f'https://api.mfapi.in/mf/{scheme_code}'
SIP Calculator
Zerodha Calculators
MF Algo test
Tijori Finance
Link: https://tijorifinance.com/
Features:
Portfolio tracking
Fund screener with advanced filters
Performance comparison
MoneyControl Mutual Fund Tools
link: https://www.moneycontrol.com/mutual-funds/
Tools available:
Fund Screener
Returns Calculator
Fund Comparison
RupeeVest Research Tools
Link: https://www.rupeevest.com/Mutual-Funds
Features:
Compare multiple funds
Risk analysis
Portfolio overlap checker
Python Library - mftool
GitHub: GitHub - NayakwadiS/mftool: ⚡ Python library for getting publically available Mutual Funds data in India
pythonCopyfrom mftool import Mftool
mf = Mftool()
# Get scheme details
scheme_info = mf.get_scheme_details('119598')
Kuvera’s Analysis Tools
Link: Kuvera :: Wealth Management Simplified
Features:
Portfolio Overlap
Fund comparison
Direct vs Regular comparison
MarketsMojo
Link: https://www.marketsmojo.com/mutualfund
Features:
Fund ratings
Risk analysis
Portfolio health check
Further, I was trying to do something related to the analysis tool and ended up creating something using AI.
Setting Up the Analysis Environment
Python environment with necessary libraries:
pip install mftool pandas numpy matplotlib streamlit plotly requests
Basic Data Extraction Script
from mftool import Mftool
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import plotly.graph_objects as go
class MFAnalyzer:
def __init__(self):
self.mf = Mftool()
def get_scheme_data(self, scheme_code):
"""Fetch scheme data and convert to DataFrame"""
scheme_data = self.mf.get_scheme_historical_nav(scheme_code)
if scheme_data is None:
return None
df = pd.DataFrame(scheme_data['data'])
df['date'] = pd.to_datetime(df['date'], format='%d-%m-%Y')
df['nav'] = pd.to_numeric(df['nav'])
return df.sort_values('date')
def calculate_returns(self, df):
"""Calculate various return metrics"""
latest_nav = df['nav'].iloc[-1]
year_ago_nav = df[df['date'] >= (datetime.now() - timedelta(days=365))]['nav'].iloc[0]
returns = {
'one_year_return': ((latest_nav - year_ago_nav) / year_ago_nav) * 100,
'volatility': df['nav'].pct_change().std() * np.sqrt(252) * 100,
'latest_nav': latest_nav
}
return returns
# Usage Example
analyzer = MFAnalyzer()
scheme_code = '119598' # SBI Blue Chip Fund-Direct Plan-Growth
df = analyzer.get_scheme_data(scheme_code)
returns = analyzer.calculate_returns(df)
print(f"One Year Return: {returns['one_year_return']:.2f}%")
print(f"Volatility: {returns['volatility']:.2f}%")
Building a Fund Comparison tool
class MFComparator:
def __init__(self):
self.analyzer = MFAnalyzer()
def compare_funds(self, scheme_codes):
"""Compare multiple funds"""
comparison_data = []
for code in scheme_codes:
scheme_info = self.analyzer.mf.get_scheme_details(code)
df = self.analyzer.get_scheme_data(code)
returns = self.analyzer.calculate_returns(df)
comparison_data.append({
'scheme_name': scheme_info['scheme_name'],
'one_year_return': returns['one_year_return'],
'volatility': returns['volatility'],
'latest_nav': returns['latest_nav'],
'category': scheme_info['scheme_category']
})
return pd.DataFrame(comparison_data)
def plot_comparison(self, scheme_codes):
"""Create comparison plot"""
fig = go.Figure()
for code in scheme_codes:
df = self.analyzer.get_scheme_data(code)
scheme_info = self.analyzer.mf.get_scheme_details(code)
# Normalize NAV values
normalized_nav = (df['nav'] / df['nav'].iloc[0]) * 100
fig.add_trace(go.Scatter(
x=df['date'],
y=normalized_nav,
name=scheme_info['scheme_name']
))
fig.update_layout(
title='Fund Comparison (Normalized Returns)',
xaxis_title='Date',
yaxis_title='Normalized NAV'
)
return fig
# Usage Example
comparator = MFComparator()
funds_to_compare = ['119598', '119727'] # Add your fund codes
comparison_df = comparator.compare_funds(funds_to_compare)
comparison_plot = comparator.plot_comparison(funds_to_compare)
Creating an Interactive Dashboard
Dashboard to visualize the analysis:
import streamlit as st
def create_dashboard():
st.title('Mutual Fund Analysis Dashboard')
# Sidebar for fund selection
st.sidebar.header('Select Funds to Analyze')
selected_funds = st.sidebar.multiselect(
'Choose funds',
['119598', '119727', '120503'], # Add more fund codes
default=['119598']
)
if selected_funds:
comparator = MFComparator()
# Show comparison table
st.subheader('Fund Comparison')
comparison_df = comparator.compare_funds(selected_funds)
st.dataframe(comparison_df)
# Show comparison plot
st.subheader('Performance Comparison')
comparison_plot = comparator.plot_comparison(selected_funds)
st.plotly_chart(comparison_plot)
# Add risk metrics
st.subheader('Risk Metrics')
for fund in selected_funds:
df = comparator.analyzer.get_scheme_data(fund)
returns = comparator.analyzer.calculate_returns(df)
st.write(f"**{comparator.analyzer.mf.get_scheme_details(fund)['scheme_name']}**")
st.write(f"Volatility: {returns['volatility']:.2f}%")
# Run dashboard
if __name__ == '__main__':
create_dashboard()
Advanced Analytics Features
Portfolio Overlap Analysis
def calculate_portfolio_overlap(scheme1_code, scheme2_code):
"""Calculate portfolio overlap between two schemes"""
mf = Mftool()
# Get portfolio holdings
scheme1_info = mf.get_scheme_details(scheme1_code)
scheme2_info = mf.get_scheme_details(scheme2_code)
# Extract stock names
scheme1_stocks = set(holding['stock_name'] for holding in scheme1_info.get('portfolio_holdings', []))
scheme2_stocks = set(holding['stock_name'] for holding in scheme2_info.get('portfolio_holdings', []))
# Calculate overlap
common_stocks = scheme1_stocks.intersection(scheme2_stocks)
overlap_percentage = (len(common_stocks) / min(len(scheme1_stocks), len(scheme2_stocks))) * 100
return {
'overlap_percentage': overlap_percentage,
'common_stocks': list(common_stocks)
}
Risk-Adjusted Returns Analysis
def calculate_risk_metrics(df):
"""Calculate advanced risk metrics"""
returns = df['nav'].pct_change()
risk_free_rate = 0.04 # Assume 4% risk-free rate
# Sharpe Ratio
excess_returns = returns - (risk_free_rate/252)
sharpe_ratio = np.sqrt(252) * excess_returns.mean() / returns.std()
# Maximum Drawdown
cumulative_returns = (1 + returns).cumprod()
rolling_max = cumulative_returns.expanding().max()
drawdowns = cumulative_returns/rolling_max - 1
max_drawdown = drawdowns.min()
return {
'sharpe_ratio': sharpe_ratio,
'max_drawdown': max_drawdown,
'annualized_volatility': returns.std() * np.sqrt(252)
}
Implementing the System
To use this complete system:
- Save the code in separate files (e.g.,
analyzer.py
, comparator.py
, dashboard.py
)
- Install required dependencies
- Run the dashboard:
streamlit run dashboard.py
Key Features of this tool:
-
Data Extraction
- Historical NAV data
- Scheme details
- Portfolio holdings
-
Analysis Capabilities
- Returns calculation
- Risk metrics
- Portfolio overlap
- Performance comparison
-
Visualization
- Interactive plots
- Comparison charts
- Risk-return scatter plots
-
Dashboard Features
- Fund selection
- Performance metrics
- Risk analysis
- Portfolio comparison
References and Resources