File size: 4,807 Bytes
dfbd37e
 
 
f823eaa
dfbd37e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f823eaa
 
 
 
 
 
dfbd37e
 
 
 
 
 
 
f823eaa
 
 
 
 
 
 
 
 
 
 
 
 
dfbd37e
 
 
 
 
 
 
 
 
 
f823eaa
dfbd37e
 
 
f823eaa
 
 
 
 
 
 
 
dfbd37e
f823eaa
dfbd37e
 
 
 
 
 
 
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
import pandas as pd
from utils import get_mf_scheme_data
from returns import get_investment_xirr, get_investment_sip_absolute_returns
from indicators import get_investment_sd, get_investment_sharpe_ratio, get_investment_indicator_report

def get_portfolio_nav_df(schemes_name_and_weight, start_date, end_date, schemes_df):
    # start_date = pd.to_datetime(start_date)
    # end_date = pd.to_datetime(end_date)

    portfolio_nav_df = pd.DataFrame()

    for scheme_name, scheme_weight in schemes_name_and_weight.items():
        scheme_code = schemes_df[schemes_df['schemeName'] == scheme_name]['schemeCode'].values[0]
        scheme_nav_df, _ = get_mf_scheme_data(scheme_code= scheme_code)
        scheme_nav_df = scheme_nav_df[(scheme_nav_df['date'] >= start_date) & (scheme_nav_df['date'] <= end_date)]
        scheme_nav_df['nav'] = scheme_nav_df['nav'] * scheme_weight / 100
        if portfolio_nav_df.empty:
            portfolio_nav_df = scheme_nav_df
        else:
            portfolio_nav_df['nav'] += scheme_nav_df['nav']

    return portfolio_nav_df


def get_portfolio_xirr_returns(portfolio_df, start_date, end_date, SIP_date, lumpsum_amount, sip_amount):
    return(get_investment_xirr(portfolio_df, start_date, end_date, SIP_date, lumpsum_amount, sip_amount))

def get_portfolio_absolute_returns(portfolio_df, sip_amount, lumpsum_amount, stepup, start_date, end_date, SIP_date):

    return (get_investment_sip_absolute_returns(portfolio_df, sip_amount, lumpsum_amount, stepup, start_date, end_date, SIP_date))

def get_invdividual_scheme_returns(scheme_df, scheme_name,scheme_sip_amount, scheme_lumpsum_amount, stepup, start_date, end_date, SIP_date):
    absolute_return, final_value, invested_value = get_investment_sip_absolute_returns(scheme_df, scheme_sip_amount, scheme_lumpsum_amount, stepup, start_date, end_date, SIP_date)
    xirr = get_investment_xirr(scheme_df, start_date, end_date, SIP_date, scheme_lumpsum_amount, scheme_sip_amount)
    scheme_string = f"""
    Scheme: {scheme_name}
    ------------------------------------
    Investment: {invested_value}
    Scheme Final Value: {final_value}
    Absolute Return: {absolute_return}%
    XIRR: {xirr}%\n
    """
    return (scheme_string)

def get_inception_date_warnings(inception_dates, start_date):
    warnings = []
    for scheme_name, scheme_inception_date in inception_dates:
        if scheme_inception_date > start_date:
            warnings.append(f"{scheme_name} has an inception date of {scheme_inception_date} which is after the start date of the portfolio.")
    return warnings


def calculate_portfolio_returns(scheme_name_and_weight, sip_amount, lumpsum_amount, stepup, start_date, end_date, SIP_date, schemes_df):
    inception_dates = []
    scheme_individual_returns = []
    portfolio_df = get_portfolio_nav_df(scheme_name_and_weight, start_date, end_date,schemes_df)
    portfolio_absolute_return, portfolio_final_value, portfolio_invested_value = get_portfolio_absolute_returns(portfolio_df, sip_amount, lumpsum_amount, stepup, start_date, end_date, SIP_date)
    portfolio_indicators_string  = get_investment_indicator_report(portfolio_df, start_date, end_date)

    for scheme_name, scheme_weight in scheme_name_and_weight.items():
        scheme_code = schemes_df[schemes_df['schemeName'] == scheme_name]['schemeCode'].values[0]
        scheme_df, scheme_inception_date = get_mf_scheme_data(scheme_code)
        inception_dates.append((scheme_name, scheme_inception_date))
        scheme_sip_amount = sip_amount * scheme_weight / 100
        scheme_lumpsum_amount = lumpsum_amount * scheme_weight / 100
        scheme_individual_returns.append(get_invdividual_scheme_returns(scheme_df, scheme_name, scheme_sip_amount, scheme_lumpsum_amount, stepup, start_date, end_date, SIP_date))

    inception_date_warnings = get_inception_date_warnings(inception_dates, start_date)

    portfolio_report_string = f"""
    Portfolio
    ------------------------------------
    SIP Amount: {sip_amount}
    Lumpsum Amount: {lumpsum_amount}
    Stepup: {stepup}
    Start Date: {start_date}
    End Date: {end_date}
    SIP Date: {SIP_date}
    Total Investment: {portfolio_invested_value}
    ------------------------------------
    Portfolio Report
    XIRR = {get_portfolio_xirr_returns(portfolio_df, start_date, end_date, SIP_date, lumpsum_amount, sip_amount)}%
    Absolute Returns = {portfolio_absolute_return}%
    Portfolio Final Value = {portfolio_final_value}
    {portfolio_indicators_string}
    ------------------------------------
    Individual Scheme Returns
    ------------------------------------
    {''.join(scheme_individual_returns)}
    ------------------------------------
    Warnings
    {''.join(inception_date_warnings)}
    """
    return portfolio_report_string