MFPack 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MFPack/MFA.py +99 -0
- MFPack/__init__.py +5 -0
- MFPack/upstox.py +72 -0
- mfpack-0.1.0.dist-info/METADATA +12 -0
- mfpack-0.1.0.dist-info/RECORD +7 -0
- mfpack-0.1.0.dist-info/WHEEL +5 -0
- mfpack-0.1.0.dist-info/top_level.txt +1 -0
MFPack/MFA.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
All Functions operate on daily NAV data only - Check the documentation for UpxPI for fetching the NAV Data
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def nav_igrow(df_nav_info,initial_investment=1000):
|
|
12
|
+
|
|
13
|
+
starting_nav = df_nav_info.iloc[0]["nav"]
|
|
14
|
+
units = initial_investment / starting_nav
|
|
15
|
+
|
|
16
|
+
df_nav_info["investment_value"] = units * df_nav_info["nav"]
|
|
17
|
+
return df_nav_info
|
|
18
|
+
|
|
19
|
+
def nav_CAGR(df_nav_info, initial_investment=1000):
|
|
20
|
+
"""
|
|
21
|
+
Returns the CAGR in regular units of 100
|
|
22
|
+
"""
|
|
23
|
+
df_nav_info = nav_igrow(df_nav_info,initial_investment)
|
|
24
|
+
start_nav = df_nav_info.iloc[0]["nav"]
|
|
25
|
+
end_nav = df_nav_info.iloc[-1]["nav"]
|
|
26
|
+
|
|
27
|
+
start_year = df_nav_info.iloc[0]["date"]
|
|
28
|
+
end_year = df_nav_info.iloc[-1]["date"]
|
|
29
|
+
|
|
30
|
+
years = (end_year - start_year).days / 365.25
|
|
31
|
+
cagr = ((end_nav / start_nav) ** (1 / years) - 1)
|
|
32
|
+
return cagr
|
|
33
|
+
|
|
34
|
+
def nav_returns(df_nav_info, initial_investment=1000):
|
|
35
|
+
df_nav_info = nav_igrow(df_nav_info,initial_investment)
|
|
36
|
+
df_nav_info["nav_returns"] = df_nav_info["investment_value"].pct_change()
|
|
37
|
+
return df_nav_info.fillna(0)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def nav_ann_returns(returns, period_per_year):
|
|
41
|
+
"""
|
|
42
|
+
Requires only the returns computed from nav_returns() function
|
|
43
|
+
"""
|
|
44
|
+
comp_growth = (1+returns).prod()
|
|
45
|
+
n_period = len(returns)
|
|
46
|
+
return comp_growth ** (period_per_year/n_period) - 1
|
|
47
|
+
|
|
48
|
+
def nav_vol(df_nav_info, initial_investment=1000):
|
|
49
|
+
returns = nav_returns(df_nav_info, initial_investment=1000)["nav_returns"]
|
|
50
|
+
return returns.std()
|
|
51
|
+
|
|
52
|
+
def nav_ann_vol(df_nav_info, initial_investment=1000):
|
|
53
|
+
returns = nav_vol(df_nav_info, initial_investment)
|
|
54
|
+
return returns * np.sqrt(252)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def nav_sharpe(df_nav_info, R_p, initial_investment=1000):
|
|
58
|
+
'''
|
|
59
|
+
Takes an additional Parameters of Risk Free Return
|
|
60
|
+
'''
|
|
61
|
+
R_f = nav_CAGR(df_nav_info, initial_investment=1000)
|
|
62
|
+
Vol = nav_vol(df_nav_info, initial_investment=1000) # This should be annualized volatility
|
|
63
|
+
|
|
64
|
+
return (R_f - R_p) / Vol
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def nav_drawdown(df_nav_info,initial_investment):
|
|
68
|
+
|
|
69
|
+
df_nav_info = nav_returns(df_nav_info,initial_investment)
|
|
70
|
+
df_nav_info["nav_drawdown"] = df_nav_info["investment_value"].cummax()
|
|
71
|
+
return df_nav_info
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def nav_fetch(schemeCode, startDate, endDate):
|
|
75
|
+
"""
|
|
76
|
+
Fetch the NAV history of a Mutual Fund using schemeCode found through nav_search() function
|
|
77
|
+
"""
|
|
78
|
+
mfapi_nav_url = f'https://api.mfapi.in/mf/{schemeCode}'
|
|
79
|
+
params = {
|
|
80
|
+
'startDate': startDate,
|
|
81
|
+
'endDate': endDate
|
|
82
|
+
}
|
|
83
|
+
nav_info = requests.get(mfapi_nav_url, params=params).json()
|
|
84
|
+
|
|
85
|
+
df_nav_info = pd.DataFrame(nav_info["data"])
|
|
86
|
+
|
|
87
|
+
df_nav_info["date"] = pd.to_datetime(df_nav_info["date"], format="%d-%m-%Y")
|
|
88
|
+
df_nav_info["nav"] = df_nav_info["nav"].astype(float)
|
|
89
|
+
df_nav_info = df_nav_info.sort_values("date")
|
|
90
|
+
return df_nav_info
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def mf_fetch(fund_name):
|
|
94
|
+
mfapi_url = 'https://api.mfapi.in/mf/search'
|
|
95
|
+
params = {'q':fund_name}
|
|
96
|
+
scheme_info = requests.get(mfapi_url, params=params).json()
|
|
97
|
+
df = pd.DataFrame(scheme_info)
|
|
98
|
+
df.set_index('schemeCode', inplace=True)
|
|
99
|
+
return df
|
MFPack/__init__.py
ADDED
MFPack/upstox.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import os
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# load_dotenv()
|
|
8
|
+
# access_token=os.getenv('ACCESS_TOKEN')
|
|
9
|
+
access_token = None
|
|
10
|
+
|
|
11
|
+
def login(_access_token):
|
|
12
|
+
"""
|
|
13
|
+
Pass the token generated here
|
|
14
|
+
"""
|
|
15
|
+
global access_token
|
|
16
|
+
access_token = _access_token
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def headers():
|
|
20
|
+
if access_token is None:
|
|
21
|
+
raise ValueError("Input login()")
|
|
22
|
+
return {
|
|
23
|
+
'accept': 'application/json',
|
|
24
|
+
'Authorization': f'Bearer {access_token}',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def holdings_data():
|
|
29
|
+
holdings_url = 'https://api.upstox.com/v2/mf/holdings'
|
|
30
|
+
holdings_data = requests.get(holdings_url, headers=headers()).json()
|
|
31
|
+
return pd.DataFrame(holdings_data["data"])
|
|
32
|
+
|
|
33
|
+
def order_book_data(records=10):
|
|
34
|
+
order_book_url = 'https://api.upstox.com/v2/mf/orders'
|
|
35
|
+
|
|
36
|
+
page_number = 1
|
|
37
|
+
all_orders = []
|
|
38
|
+
|
|
39
|
+
while True:
|
|
40
|
+
params = {
|
|
41
|
+
'page_number':page_number,
|
|
42
|
+
'records':records
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
response = requests.get(order_book_url, params=params, headers=headers()).json()
|
|
46
|
+
data = response['data']
|
|
47
|
+
if not data:
|
|
48
|
+
break
|
|
49
|
+
all_orders.extend(data)
|
|
50
|
+
print(f"Fetched page {page_number} ({len(data)} records)")
|
|
51
|
+
page_number += 1
|
|
52
|
+
return pd.DataFrame(all_orders)
|
|
53
|
+
|
|
54
|
+
def order_details_data(order_id):
|
|
55
|
+
''' This rrequires an input parameter of order ID, fetched using order_book_date() method'''
|
|
56
|
+
order_details_url = f'https://api.upstox.com/v2/mf/orders/{order_id}'
|
|
57
|
+
order_details_data = requests.get(order_details_url, headers=headers()).json()
|
|
58
|
+
return pd.DataFrame(order_details_data)
|
|
59
|
+
|
|
60
|
+
def sip_data():
|
|
61
|
+
sip_url = 'https://api.upstox.com/v2/mf/sips'
|
|
62
|
+
sip_data = requests.get(sip_url, headers=headers()).json()
|
|
63
|
+
return pd.DataFrame(sip_data["data"])
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def fund_history(instrument_key):
|
|
67
|
+
data = order_book_data()
|
|
68
|
+
return data[
|
|
69
|
+
(data['instrument_key'] == instrument_key)
|
|
70
|
+
& (data['status'] == 'COMPLETED')
|
|
71
|
+
& (data['transaction_type'] == 'BUY')
|
|
72
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: MFPack
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Analytics library for your investments
|
|
5
|
+
Author: Nayan
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: pandas
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: matplotlib
|
|
11
|
+
Requires-Dist: requests
|
|
12
|
+
Requires-Dist: scipy
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
MFPack/MFA.py,sha256=btgNdA-KmA1WECoB8taVZumWvhCbrH9WhPElOyJf2vM,3143
|
|
2
|
+
MFPack/__init__.py,sha256=7mboQ0EFVyJPiOs_fHa_LZVnWMCHqLCd57XpWEb3-V8,49
|
|
3
|
+
MFPack/upstox.py,sha256=OjoTEX6hGKm1hcz1Q9pSvGOq_Jg2YRtQ5SsvRAMOito,2008
|
|
4
|
+
mfpack-0.1.0.dist-info/METADATA,sha256=FJVTTCbEjwaCtauZuQ6Iidf6vU3j9uE0cngH4iYFbto,290
|
|
5
|
+
mfpack-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
6
|
+
mfpack-0.1.0.dist-info/top_level.txt,sha256=t-Kzrxdu9NlMvHlMT-6cwzvJzNO0V8iJ8AANF32gpfI,7
|
|
7
|
+
mfpack-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MFPack
|