Price forecasting of SGB and IRFC Bonds and comparing there returns

Overview

Project_Bonds

Project Title : Price forecasting of SGB and IRFC Bonds and comparing there returns.

Introduction of the Project

The 2008-09 global financial crises and 2020-21 pandemic have shown us the volatility of the market. Many people have are finding a way to invest money to secure their future. People are trying to find a secure investment with minimum financial risks with higher returns. This is also a fact that with investment their also comes with risks. There is a saying in the world of investment “Do not put all your egg in one basket”. We need to diverse portfolio in the area of investment, so that if one investment does not give you enough yields due to fluctuations in the market rates then other will give you higher yield. Bonds are one such investment people prefer the most. The Bonds we have selected are two government bonds – SGB (Sovereign Gold Bond) and IRFC (Indian Railway Finance Corporation). The objective was to forecast the prices of SGB and IRFC bond and calculate the returns. Compare the returns and recommend the client which one to pick based on the input that is number of years to forecast.

Technologies Used

  • Python – ML model (auto_arima (for grid search to find p,q,d values), ARIMA(for forecasting values))
  • SQLite – Database
  • Flask – Front End for deployment
  • Python Libraries – numpy, pandas, Statsmodels, re, nsepy, matplotlib
  • HTML/CSS

General info

This project is simple Forecasting model. Not taxes were put into use when calculating returns. IRFC Bond is a tax free bond but SGB we need to pay taxes if we try to sell it before the maturity period is over. Inflation rate and global pandemic situation is a rare phenonmenon and it is beyond anyone's control. It has been taken into business restriction.
Data has been collected from National Stock exchange of India The two bonds selected from NSE was -

Requirement file (contains libraries and their versions)

Libraries Used

Project Architecture

alt text

Explaining Project Architecture

Live data extraction

The data collected from NSE website (historical data) and the library which is used to collect live daily data from the website is nsepy. The data is then goes to python, two things happens in python. First, out of all the attributes, we only take "Close Price" and then the daily is then converted into monthly data. We use mean to calculate the the monthly average.

Data storage in sqlite

We chose SQLite because it is very easy to use and one does not need the knowledge of sql to observe the data. the database is created locally and and is being updated when the user usses the application. the user can easliy take the database and see the data in SQL viewr online available.

Data is then used by the model

When data is then called back by the python. the python then perform differencing method to remove the trend and seasonality from the data so that our data can be stable. For successful forecasting, it is necessary to keepp the time series data to be stationary.

p,d,q Hyperparameters

We use auto_arima function to calculate p,d,q value. We use re(regex) to store the summary of auto_arima in string format. then use "re.findall()" funtion to collect the value of p,d,q values. The downpoint of using this auto_arima function is that it runs two times when the programes gets executed. It calculate the hyperparameter values for both SGB and IRFC data.

ARIMA

This part is where the data is taken and then fit & predict.
This is for 12 months. Actual Data vs Predicted Data

Model Evaluation

SGB

The RMSE: 93.27 Rs. & The MAPE: 0.0185

IRFC

The RMSE: 21.62 Rs. & The MAPE: 0.0139
(Pretty Good)

Forecasting (12 Months)

Forecasted Data (12 Months)

Returns

This is the part where both SGB and IRFC foecasted data is being collected and based on that returns are calculated. If the SGB returns is higher than IRFC bonds then it will tell the customer about the amount of return for a specific time period.

User Input

The user will be given 3 options as Input. The user will select a specific time period from a drop down list. The options are -

  1. 4 Months (Quaterly)
  2. 6 Months (Half yearly)
  3. 12 Months (Anually)
    This options are time pperiod to forecast. If the user press 6 then the output page will show "6" forecasted values with a range Upper Price, Forecasted Price, Lower Price for both the bonds side by side. Below there will be a text where the returns will be diplayed if the user decides to sell the bonds then.
    12 Months Forecasted Prices - forecasted_prices

Python_code

correlation matrix fig=plt.gcf() fig.set_size_inches(10,8) plt.show() heatmap(gold) heatmap(bond) ############################### Live data to Feature engineering ################################################3 ##Taking close price as our univariate variable ##For gold gold=pd.DataFrame(gold["Close"]) gold["date"]=gold.index gold["date"]=gold['date'].astype(str) gold[["year", "month", "day"]] = gold["date"].str.split(pat="-", expand=True) gold['Dates'] = gold['month'].str.cat(gold['year'], sep ="-") gold.Dates=pd.to_datetime(gold.Dates) gold.set_index('Dates',inplace=True) col_sgb=pd.DataFrame(gold.groupby(gold.index).Close.mean()) ##For bond bond=pd.DataFrame(bond["Close"]) bond["date"]=bond.index bond["date"]=bond['date'].astype(str) bond[["year", "month", "day"]] = bond["date"].str.split(pat="-", expand=True) bond['Dates'] = bond['month'].str.cat(bond['year'], sep ="-") bond.Dates=pd.to_datetime(bond.Dates) bond.set_index('Dates',inplace=True) col_bond=pd.DataFrame(bond.groupby(bond.index).Close.mean()) col_sgb.columns = ["Avg_price"] col_bond.columns = ["Avg_price"] col_bond.isnull().sum() col_sgb.isnull().sum() ############################ SQL connection with monthly data ################################################ ############################### SQL database is created ################################################3 # Connect to the database from sqlalchemy import create_engine engine_sgb = create_engine('sqlite:///gold_database.db', echo=False) col_sgb.to_sql('SGB', con=engine_sgb,if_exists='replace') df_sgb = pd.read_sql('select * from SGB',engine_sgb ) df_sgb.Dates=pd.to_datetime(df_sgb.Dates) df_sgb.set_index('Dates',inplace=True) engine_irfcb = create_engine('sqlite:///irfcb_database.db', echo=False) col_bond.to_sql('IRFCB', con=engine_irfcb,if_exists='replace') df_bond = pd.read_sql('select * from IRFCB',engine_irfcb) df_bond.Dates=pd.to_datetime(df_bond.Dates) df_bond.set_index('Dates',inplace=True) ############################### SQL data to python ################################################3 # Plotting def plotting_bond(y): fig, ax = plt.subplots(figsize=(20, 6)) ax.plot(y,marker='.', linestyle='-', linewidth=0.5, label='Monthly Average') ax.plot(y.resample('Y').mean(),marker='o', markersize=8, linestyle='-', label='Yearly Mean Resample') ax.set_ylabel('Avg_price') ax.legend(); plotting_bond(df_sgb) plotting_bond(df_bond) #univariate analysis of Average Price df_sgb.hist(bins = 50) df_bond.hist(bins = 50) # check Stationary and adf test def test_stationarity(timeseries): #Determing rolling statistics rolmean = timeseries.rolling(12).mean() rolstd = timeseries.rolling(12).std() #Plot rolling statistics: fig, ax = plt.subplots(figsize=(16, 4)) ax.plot(timeseries, label = "Original Price") ax.plot(rolmean, label='rolling mean'); ax.plot(rolstd, label='rolling std'); plt.legend(loc='best') plt.title('Rolling Mean and Standard Deviation - Removed Trend and Seasonality') plt.show(block=False) print("Results of dickey fuller test") adft = adfuller(timeseries,autolag='AIC') print('Test statistic = {:.3f}'.format(adft[0])) print('P-value = {:.3f}'.format(adft[1])) print('Critical values :') for k, v in adft[4].items(): print('\t{}: {} - The data is {} stationary with {}% confidence'.format(k, v, 'not' if v y: a = print("The retrun of SGB is {a} and the return of IRFC Bond is {b} after {c} months".format(a=x,b=y,c=t)) else: a = print("The return of IRFC Bond is{a} and the return of SGB Bond is {b} after {c} months".format(a=x,b=y,c=t)) return a output_(gain_sgb,gain_bond, n) ">
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from pylab import rcParams
from statsmodels.tsa.stattools import adfuller
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.arima.model import ARIMA
from pmdarima.arima import auto_arima
from sklearn.metrics import mean_squared_error
import math
import re
from datetime import date
import nsepy 
import warnings
warnings.filterwarnings("ignore")
####################################          Live data extraction              ###################################################
##Extracting data from nsepy package
da=date.today()
gold= pd.DataFrame(nsepy.get_history(symbol="SGBAUG24",series="GB", start=date(2016,9,1), end=da))
bond= pd.DataFrame(nsepy.get_history(symbol="IRFC",series="N2", start=date(2012,1,1), end=da))

#############################                 Live data  extraction end                  ###############################################

# Heatmap - to check collinearity
def heatmap(x):
    plt.figure(figsize=(16,16))
    sns.heatmap(x.corr(),annot=True,cmap='Blues',linewidths=0.2) #data.corr()-->correlation matrix
    fig=plt.gcf()
    fig.set_size_inches(10,8)
    plt.show()
heatmap(gold)
heatmap(bond)
###############################                Live data to Feature engineering            ################################################3             

##Taking close price as our univariate variable
##For gold
gold=pd.DataFrame(gold["Close"])
gold["date"]=gold.index
gold["date"]=gold['date'].astype(str)
gold[["year", "month", "day"]] = gold["date"].str.split(pat="-", expand=True)
gold['Dates'] = gold['month'].str.cat(gold['year'], sep ="-")
gold.Dates=pd.to_datetime(gold.Dates)
gold.set_index('Dates',inplace=True)
col_sgb=pd.DataFrame(gold.groupby(gold.index).Close.mean())

##For bond
bond=pd.DataFrame(bond["Close"])
bond["date"]=bond.index
bond["date"]=bond['date'].astype(str)
bond[["year", "month", "day"]] = bond["date"].str.split(pat="-", expand=True)
bond['Dates'] = bond['month'].str.cat(bond['year'], sep ="-")
bond.Dates=pd.to_datetime(bond.Dates)
bond.set_index('Dates',inplace=True)
col_bond=pd.DataFrame(bond.groupby(bond.index).Close.mean())

col_sgb.columns = ["Avg_price"]
col_bond.columns = ["Avg_price"]

col_bond.isnull().sum()
col_sgb.isnull().sum()

############################                  SQL connection with monthly data           ################################################ 
###############################                SQL database is created                  ################################################3             

# Connect to the database
from sqlalchemy import create_engine
engine_sgb = create_engine('sqlite:///gold_database.db', echo=False)
col_sgb.to_sql('SGB', con=engine_sgb,if_exists='replace')
df_sgb = pd.read_sql('select * from SGB',engine_sgb )

df_sgb.Dates=pd.to_datetime(df_sgb.Dates)
df_sgb.set_index('Dates',inplace=True)


engine_irfcb = create_engine('sqlite:///irfcb_database.db', echo=False)
col_bond.to_sql('IRFCB', con=engine_irfcb,if_exists='replace')
df_bond = pd.read_sql('select * from IRFCB',engine_irfcb)

df_bond.Dates=pd.to_datetime(df_bond.Dates)
df_bond.set_index('Dates',inplace=True)
###############################                SQL data to python                 ################################################3             



# Plotting
def plotting_bond(y):
    fig, ax = plt.subplots(figsize=(20, 6))
    ax.plot(y,marker='.', linestyle='-', linewidth=0.5, label='Monthly Average')
    ax.plot(y.resample('Y').mean(),marker='o', markersize=8, linestyle='-', label='Yearly Mean Resample')
    ax.set_ylabel('Avg_price')
    ax.legend();
plotting_bond(df_sgb)
plotting_bond(df_bond)

#univariate analysis of Average Price
df_sgb.hist(bins = 50)
df_bond.hist(bins = 50)

# check Stationary and adf test
def test_stationarity(timeseries):
    #Determing rolling statistics
    rolmean = timeseries.rolling(12).mean()
    rolstd = timeseries.rolling(12).std()
    #Plot rolling statistics:
    fig, ax = plt.subplots(figsize=(16, 4))
    ax.plot(timeseries, label = "Original Price")
    ax.plot(rolmean, label='rolling mean');
    ax.plot(rolstd, label='rolling std');
    plt.legend(loc='best')
    plt.title('Rolling Mean and Standard Deviation - Removed Trend and Seasonality')
    plt.show(block=False)
    
    print("Results of dickey fuller test")
    adft = adfuller(timeseries,autolag='AIC')
    print('Test statistic = {:.3f}'.format(adft[0]))
    print('P-value = {:.3f}'.format(adft[1]))
    print('Critical values :')
    for k, v in adft[4].items():
        print('\t{}: {} - The data is {} stationary with {}% confidence'.format(k, v, 'not' if v
    
      y:
        a = print("The retrun of SGB is {a} and the return of IRFC Bond is {b} after {c} months".format(a=x,b=y,c=t))
    else:
        a = print("The return of IRFC Bond is{a} and the return of SGB Bond is {b} after {c} months".format(a=x,b=y,c=t))
    return a
output_(gain_sgb,gain_bond, n)

    

Home Page (Used HTML and CSS)

home

Predict Page

predict

Output Page

output

Project Completed --

Owner
Tishya S
Data Science aspirant
Tishya S
Accelerating model creation and evaluation.

EmeraldML A machine learning library for streamlining the process of (1) cleaning and splitting data, (2) training, optimizing, and testing various mo

Yusuf 0 Dec 06, 2021
A library to generate synthetic time series data by easy-to-use factors and generator

timeseries-generator This repository consists of a python packages that generates synthetic time series dataset in a generic way (under /timeseries_ge

Nike Inc. 87 Dec 20, 2022
scikit-fem is a lightweight Python 3.7+ library for performing finite element assembly.

scikit-fem is a lightweight Python 3.7+ library for performing finite element assembly. Its main purpose is the transformation of bilinear forms into sparse matrices and linear forms into vectors.

Tom Gustafsson 297 Dec 13, 2022
Python Automated Machine Learning library for tabular data.

Simple but powerful Automated Machine Learning library for tabular data. It uses efficient in-memory SAP HANA algorithms to automate routine Data Scie

Daniel Khromov 47 Dec 17, 2022
A Powerful Serverless Analysis Toolkit That Takes Trial And Error Out of Machine Learning Projects

KXY: A Seemless API to 10x The Productivity of Machine Learning Engineers Documentation https://www.kxy.ai/reference/ Installation From PyPi: pip inst

KXY Technologies, Inc. 35 Jan 02, 2023
PyCaret is an open-source, low-code machine learning library in Python that automates machine learning workflows.

An open-source, low-code machine learning library in Python 🚀 Version 2.3.5 out now! Check out the release notes here. Official • Docs • Install • Tu

PyCaret 6.7k Jan 08, 2023
Python factor analysis library (PCA, CA, MCA, MFA, FAMD)

Prince is a library for doing factor analysis. This includes a variety of methods including principal component analysis (PCA) and correspondence anal

Max Halford 915 Dec 31, 2022
LinearRegression2 Tvads and CarSales

LinearRegression2_Tvads_and_CarSales This project infers the insight that how the TV ads for cars and car Sales are being linked with each other. It i

Ashish Kumar Yadav 1 Dec 29, 2021
Add built-in support for quaternions to numpy

Quaternions in numpy This Python module adds a quaternion dtype to NumPy. The code was originally based on code by Martin Ling (which he wrote with he

Mike Boyle 531 Dec 28, 2022
ELI5 is a Python package which helps to debug machine learning classifiers and explain their predictions

A library for debugging/inspecting machine learning classifiers and explaining their predictions

154 Dec 17, 2022
💀mummify: a version control tool for machine learning

mummify is a version control tool for machine learning. It's simple, fast, and designed for model prototyping.

Max Humber 43 Jul 09, 2022
Tools for Optuna, MLflow and the integration of both.

HPOflow - Sphinx DOC Tools for Optuna, MLflow and the integration of both. Detailed documentation with examples can be found here: Sphinx DOC Table of

Telekom Open Source Software 17 Nov 20, 2022
Open MLOps - A Production-focused Open-Source Machine Learning Framework

Open MLOps - A Production-focused Open-Source Machine Learning Framework Open MLOps is a set of open-source tools carefully chosen to ease user experi

Data Revenue 590 Dec 28, 2022
Machine learning model evaluation made easy: plots, tables, HTML reports, experiment tracking and Jupyter notebook analysis.

sklearn-evaluation Machine learning model evaluation made easy: plots, tables, HTML reports, experiment tracking, and Jupyter notebook analysis. Suppo

Eduardo Blancas 354 Dec 31, 2022
Python package for concise, transparent, and accurate predictive modeling

Python package for concise, transparent, and accurate predictive modeling. All sklearn-compatible and easy to use. 📚 docs • 📖 demo notebooks Modern

Chandan Singh 983 Jan 01, 2023
Machine Learning from Scratch

Machine Learning from Scratch Author: Shengxuan Wang From: Oregon State University Content: Building Machine Learning model from Scratch, without usin

ShawnWang 0 Jul 05, 2022
Responsible Machine Learning with Python

Examples of techniques for training interpretable ML models, explaining ML models, and debugging ML models for accuracy, discrimination, and security.

ph_ 624 Jan 06, 2023
Automatic extraction of relevant features from time series:

tsfresh This repository contains the TSFRESH python package. The abbreviation stands for "Time Series Feature extraction based on scalable hypothesis

Blue Yonder GmbH 7k Jan 06, 2023
Short PhD seminar on Machine Learning Security (Adversarial Machine Learning)

Short PhD seminar on Machine Learning Security (Adversarial Machine Learning)

141 Dec 27, 2022
A Python implementation of the Robotics Toolbox for MATLAB

Robotics Toolbox for Python A Python implementation of the Robotics Toolbox for MATLAB® GitHub repository Documentation Wiki (examples and details) Sy

Peter Corke 1.2k Jan 07, 2023