Building Tools with Mutual Fund Data: A Quick Guide

If you are working on a project involving mutual funds, whether it’s a chatbot, analytics tool, or even for a general deep dive, finding reliable data is the first step. Here is a concise guide to help you get started, along with a public library of resources that @Neelesh helped me compile.


Key Data Sources for Mutual Fund Projects

1. AMFI’s NAV Data

AMFI offers a daily NAV list for all active mutual fund schemes. This resource provides scheme names, ISINs, closing NAVs, and fund categories in one convenient file - making it easy to track fund values and update your investment database.


2. SEBI’s Mutual Fund Documents

SEBI offers three key mutual fund documents to help investors. The KIM gives you a quick summary of the fund’s goals, risks, and fees. The SID provides deeper details about investment strategies and risks. The SAI covers the operational side - how the fund works, fees, taxes, and your rights as an investor. Together, these documents help you understand exactly what you’re investing in.


Public Library of Resources

Here are the links:

  1. AMFI NAV Data: Link
  2. SEBI KIM: Link
  3. SEBI SID: Link
  4. SEBI SAI: Link

If you know of other useful sources or tools, please share them in the thread.

10 Likes

You can also refer to some more below :slight_smile:

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:

  1. Save the code in separate files (e.g., analyzer.py, comparator.py, dashboard.py)
  2. Install required dependencies
  3. Run the dashboard:
    streamlit run dashboard.py
    

Key Features of this tool:

  1. Data Extraction

    • Historical NAV data
    • Scheme details
    • Portfolio holdings
  2. Analysis Capabilities

    • Returns calculation
    • Risk metrics
    • Portfolio overlap
    • Performance comparison
  3. Visualization

    • Interactive plots
    • Comparison charts
    • Risk-return scatter plots
  4. Dashboard Features

    • Fund selection
    • Performance metrics
    • Risk analysis
    • Portfolio comparison

References and Resources

10 Likes

Also

1 Like

Kaggle Dataset with the data on the internet:

2 Likes