File size: 6,584 Bytes
4ce9f7c e1354e7 4ce9f7c 8637176 e1354e7 4ce9f7c e1354e7 a213323 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 2a24197 e1354e7 a98102e e1354e7 2a24197 e1354e7 e1e51b3 2a24197 91e7fe7 e1e51b3 a25f51b 2a24197 e1354e7 12b3a61 e1354e7 e1e51b3 952bb21 e1354e7 24feab2 b310efb 82d9e6e a25f51b 91e7fe7 2576813 a18e666 4ce9f7c a18e666 d02b8b8 64fe45f a18e666 5444e32 24feab2 a18e666 82d9e6e 4ce9f7c b310efb |
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
import gradio as gr
import matplotlib.pyplot as plt
import pandas as pd
import sqlite3
from datetime import datetime
import sqlite3
from datetime import datetime
# Initialize variables
db_path = 'nifty50_stock_data.db' # Database path
nifty_50_symbols = pd.read_csv("nifty50-stock-tickers.csv").Symbol.to_list() # NIFTY 50 stock symbols
class Stock:
def __init__(self, symbol, db_path, start_date, end_date):
self.symbol = symbol
self.db_path = db_path
self.start_date = start_date
self.end_date = end_date
self.prices = self._download_prices()
def _download_prices(self):
conn = sqlite3.connect(self.db_path)
query = f"SELECT Date, Close FROM `{self.symbol}` WHERE Date BETWEEN '{self.start_date}' AND '{self.end_date}'"
prices = pd.read_sql_query(query, conn, parse_dates=['Date'])
prices.set_index('Date', inplace=True)
prices.ffill(inplace=True)
return prices
def CurPrice(self, curDate):
return self.prices.loc[curDate, 'Close'] if curDate in self.prices.index else None
def NDayRet(self, N, curDate):
if curDate not in self.prices.index:
return None
start_date = self.prices.index[self.prices.index.get_loc(curDate) - N]
start_price = self.prices.loc[start_date, 'Close']
end_price = self.prices.loc[curDate, 'Close']
return (end_price - start_price) / start_price
def DailyRet(self, curDate):
if curDate not in self.prices.index:
return None
previous_date = self.prices.index[self.prices.index.get_loc(curDate) - 1]
previous_price = self.prices.loc[previous_date, 'Close']
current_price = self.prices.loc[curDate, 'Close']
return (current_price - previous_price) / previous_price
def Last30daysPrice(self, curDate):
end_loc = self.prices.index.get_loc(curDate) + 1
start_loc = max(0, end_loc - 30)
return self.prices.iloc[start_loc:end_loc]['Close'].values
# Function to calculate monthly and daily percentage change
def calculate_percentage_changes(stocks):
monthly_pct_change = pd.DataFrame()
for symbol, stock_obj in stocks.items():
monthly_pct_change[symbol] = stock_obj.prices['Close'].resample('M').last().pct_change()
monthly_pct_change.fillna(0, inplace=True)
return monthly_pct_change
# Function to update stock investments
def update_stock_investments(monthly_pct_change, month_index, stock_investments):
month = monthly_pct_change.index[month_index]
month_performance = monthly_pct_change.loc[month]
positive_stocks = [stock for stock, pct_change in month_performance.items() if pct_change > 0]
portfolio_value = sum(stock_investments.iloc[month_index - 1][symbol] * (1 + monthly_pct_change.at[month, symbol])
for symbol in nifty_50_symbols if pd.notna(monthly_pct_change.at[month, symbol]))
if positive_stocks:
investment_per_positive_stock = portfolio_value / len(positive_stocks)
stock_investments.loc[month] = {stock: investment_per_positive_stock if stock in positive_stocks else 0 for stock in nifty_50_symbols}
else:
stock_investments.loc[month] = 0
return portfolio_value
def calculate_portfolio(start_date, end_date, investment_amount):
# Initialize stock dataframes and stocks object
stocks = {symbol: Stock(symbol, db_path, start_date, end_date) for symbol in nifty_50_symbols}
monthly_pct_change = calculate_percentage_changes(stocks)
stock_investments = pd.DataFrame(index=monthly_pct_change.index, columns=nifty_50_symbols)
portfolio_returns = pd.DataFrame(index=monthly_pct_change.index, columns=["portfolio_returns"])
# Initialize stock investments
num_stocks = len(nifty_50_symbols)
investment_per_stock = investment_amount / num_stocks
stock_investments.iloc[0] = investment_per_stock
# Calculate portfolio returns
for month_index in range(1, len(monthly_pct_change.index)):
portfolio_value = update_stock_investments(monthly_pct_change, month_index, stock_investments)
portfolio_returns.at[monthly_pct_change.index[month_index], 'portfolio_returns'] = portfolio_value
# Create Stock object and Calculate monthly returns for NIFTY50
nifty_50_stock = Stock('NIFTY50', db_path, start_date, end_date)
nifty_50_monthly_return = nifty_50_stock.prices['Close'].resample('M').last().pct_change()
nifty_50_portfolio_change = nifty_50_monthly_return*(investment_amount)
nifty_50_portfolio_value =nifty_50_portfolio_change.cumsum()+investment_amount
return portfolio_returns, nifty_50_portfolio_value
def calculate_cagr(final_value, initial_value, start_date, end_date):
num_years = (pd.to_datetime(end_date) - pd.to_datetime(start_date)).days / 365.25
return (final_value / initial_value) ** (1 / num_years) - 1
def plot_chart(start_date, end_date, investment_amount):
portfolio_returns, nifty_50_portfolio_value = calculate_portfolio(start_date, end_date, investment_amount)
portfolio_cagr = calculate_cagr(portfolio_returns.iloc[-1], investment_amount, start_date, end_date)[0]
nifty50_cagr = calculate_cagr(nifty_50_portfolio_value.iloc[-1], investment_amount, start_date, end_date)
# Visualization
plt.figure(figsize=(14, 10))
plt.plot(portfolio_returns.index, portfolio_returns, label=f'Portfolio (CAGR: {portfolio_cagr*100:.2f}%)')
plt.plot(nifty_50_portfolio_value.index, nifty_50_portfolio_value, label=f'NIFTY 50 (CAGR: {nifty50_cagr*100:.2f}%)')
plt.title('Portfolio Returns Vs NIFTY 50 Returns Over Time')
plt.xlabel('Date')
plt.ylabel('Portfolio Value (in Rupees)')
plt.legend()
plt.grid(True)
plt.savefig('portfolio_chart.png')
plt.show()
print(portfolio_cagr)
print(nifty50_cagr)
return 'portfolio_chart.png'
# Markdown text to be displayed
markdown_text = """
This interface allows you to test a stock selection strategy on nifty50 stocks and compare it with the return of nifty50 index.
Please pick a date range from **2009-01-01 to 2024-01-06**
Please reload the page if you are facing connection timeout / connection errored out """
# Gradio interface
iface = gr.Interface(
fn=plot_chart,
inputs=[
gr.Textbox(label="Start Date (YYYY-MM-DD)"),
gr.Textbox(label="End Date (YYYY-MM-DD)"),
gr.Number(label="Investment Amount (in Rupees)")
],
outputs=[
gr.Image(type="filepath"),
],
title="Stock Portfolio Performance",
description=markdown_text # Adding markdown text to the description
)
iface.launch()
|