jarvisx17 commited on
Commit
71c5dc5
·
verified ·
1 Parent(s): 4f3e9a9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -0
app.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ from utils import *
4
+
5
+ st.title("Stock Portfolio and Tax Analysis")
6
+
7
+ # Initialize empty dataframes for stock sales and portfolio stocks
8
+ if 'stock_sales' not in st.session_state:
9
+ st.session_state.stock_sales = pd.DataFrame(columns=['Name', 'Sale Price', 'Purchase Price', 'Holding Period (Months)'])
10
+ if 'portfolio_stocks' not in st.session_state:
11
+ st.session_state.portfolio_stocks = pd.DataFrame(columns=['Name', 'Purchase Price', 'Current Price', 'Quantity'])
12
+
13
+ # Define function to add stock sale
14
+ def add_stock_sale():
15
+ with st.form(key="stock_sale_form"):
16
+ col1, col2, col3, col4, col5 = st.columns(5)
17
+ with col1:
18
+ name = st.text_input("Stock Name", key="stock_sale_name")
19
+ with col2:
20
+ sale_price = st.number_input("Sale Price", min_value=1.0, key="stock_sale_price")
21
+ with col3:
22
+ purchase_price = st.number_input("Purchase Price", min_value=1.0, key="stock_sale_purchase_price")
23
+ with col4:
24
+ sell_quantity = st.number_input("Quantity", min_value=10, key="stock_sale_qty")
25
+ with col5:
26
+ holding_period_months = st.number_input("Holding Period (Months)", min_value=1, key="stock_sale_holding_period")
27
+
28
+ submit_button = st.form_submit_button("Add Stock Sale")
29
+ if submit_button:
30
+ new_stock = pd.DataFrame([{'Name': name, 'Sale Price': sale_price, 'Purchase Price': purchase_price, 'Quantity': sell_quantity, 'Holding Period (Months)': holding_period_months}])
31
+ st.session_state.stock_sales = pd.concat([st.session_state.stock_sales, new_stock], ignore_index=True)
32
+ st.success("Stock Sale Added!")
33
+
34
+ # Define function to add portfolio stock
35
+ def add_portfolio_stock():
36
+ with st.form(key="portfolio_stock_form"):
37
+ col1, col2, col3, col4 = st.columns(4)
38
+ with col1:
39
+ name = st.text_input("Stock Name", key="portfolio_stock_name")
40
+ with col2:
41
+ purchase_price = st.number_input("Purchase Price", min_value=0.0, key="portfolio_stock_purchase_price")
42
+ with col3:
43
+ current_price = st.number_input("Current Price", min_value=0.0, key="portfolio_stock_current_price")
44
+ with col4:
45
+ quantity = st.number_input("Quantity", min_value=0, key="portfolio_stock_quantity")
46
+
47
+ submit_button = st.form_submit_button("Add Portfolio Stock")
48
+ if submit_button:
49
+ new_stock = pd.DataFrame([{'Name': name, 'Purchase Price': purchase_price, 'Current Price': current_price, 'Quantity': quantity}])
50
+ st.session_state.portfolio_stocks = pd.concat([st.session_state.portfolio_stocks, new_stock], ignore_index=True)
51
+ st.success("Stock Added to Portfolio!")
52
+
53
+ # Define functions to edit and delete stocks
54
+ def delete_stock_sale(index):
55
+ st.session_state.stock_sales = st.session_state.stock_sales.drop(index).reset_index(drop=True)
56
+ st.success("Stock Sale Deleted!")
57
+
58
+ def delete_portfolio_stock(index):
59
+ st.session_state.portfolio_stocks = st.session_state.portfolio_stocks.drop(index).reset_index(drop=True)
60
+ st.success("Stock Deleted from Portfolio!")
61
+
62
+ def edit_stock_sale(index, name, sale_price, purchase_price, holding_period_months):
63
+ st.session_state.stock_sales.at[index, 'Name'] = name
64
+ st.session_state.stock_sales.at[index, 'Sale Price'] = sale_price
65
+ st.session_state.stock_sales.at[index, 'Purchase Price'] = purchase_price
66
+ st.session_state.stock_sales.at[index, 'Quantity'] = sell_quantity
67
+ st.session_state.stock_sales.at[index, 'Holding Period (Months)'] = holding_period_months
68
+ st.success("Stock Sale Updated!")
69
+
70
+ def edit_portfolio_stock(index, name, purchase_price, current_price, quantity):
71
+ st.session_state.portfolio_stocks.at[index, 'Name'] = name
72
+ st.session_state.portfolio_stocks.at[index, 'Purchase Price'] = purchase_price
73
+ st.session_state.portfolio_stocks.at[index, 'Current Price'] = current_price
74
+ st.session_state.portfolio_stocks.at[index, 'Quantity'] = quantity
75
+ st.success("Portfolio Stock Updated!")
76
+
77
+ # UI Tabs
78
+ tabs = st.tabs(["Add Stocks", "Manage Stocks", "Tax Analysis"])
79
+
80
+ with tabs[0]:
81
+ st.header("Add New Stock Sale and Portfolio Stock")
82
+ st.subheader("Stock Sale")
83
+ add_stock_sale()
84
+ st.subheader("Portfolio Stock")
85
+ add_portfolio_stock()
86
+
87
+ with tabs[1]:
88
+ st.header("Manage Stocks")
89
+
90
+ st.subheader("Stock Sales")
91
+ st.dataframe(st.session_state.stock_sales)
92
+
93
+ if st.session_state.stock_sales.shape[0] > 0:
94
+ selected_sale_index = st.selectbox("Select Sale to Edit", range(st.session_state.stock_sales.shape[0]), key="select_sale_to_edit")
95
+ selected_sale = st.session_state.stock_sales.iloc[selected_sale_index]
96
+ with st.form(key="edit_stock_sale_form"):
97
+ col1, col2, col3, col4, col5 = st.columns(5)
98
+ with col1:
99
+ name = st.text_input("Edit Stock Sale Name", selected_sale['Name'], key="edit_stock_sale_name")
100
+ with col2:
101
+ sale_price = st.number_input("Edit Sale Price", min_value=0.0, value=selected_sale['Sale Price'], key="edit_stock_sale_price")
102
+ with col3:
103
+ purchase_price = st.number_input("Edit Purchase Price", min_value=0.0, value=selected_sale['Purchase Price'], key="edit_stock_sale_purchase_price")
104
+ with col4:
105
+ sell_quantity = st.number_input("Quantity", min_value=0.0, value=selected_sale['Quantity'], key="edit_stock_sale_qty")
106
+ with col5:
107
+ holding_period_months = st.number_input("Edit Holding Period (Months)", min_value=0, value=selected_sale['Holding Period (Months)'], key="edit_stock_sale_holding_period")
108
+
109
+ update_button = st.form_submit_button("Update Stock Sale")
110
+ if update_button:
111
+ edit_stock_sale(selected_sale_index, name, sale_price, purchase_price, holding_period_months)
112
+
113
+ delete_button = st.button("Delete Stock Sale", key="delete_stock_sale_button")
114
+ if delete_button:
115
+ delete_stock_sale(selected_sale_index)
116
+
117
+ st.subheader("Portfolio Stocks")
118
+ st.dataframe(st.session_state.portfolio_stocks)
119
+
120
+ if st.session_state.portfolio_stocks.shape[0] > 0:
121
+ selected_stock_index = st.selectbox("Select Portfolio Stock to Edit", range(st.session_state.portfolio_stocks.shape[0]), key="select_stock_to_edit_portfolio")
122
+ selected_stock = st.session_state.portfolio_stocks.iloc[selected_stock_index]
123
+ with st.form(key="edit_portfolio_stock_form"):
124
+ col1, col2, col3, col4 = st.columns(4)
125
+ with col1:
126
+ name = st.text_input("Edit Portfolio Stock Name", selected_stock['Name'], key="edit_portfolio_stock_name")
127
+ with col2:
128
+ purchase_price = st.number_input("Edit Purchase Price", min_value=0.0, value=selected_stock['Purchase Price'], key="edit_portfolio_stock_purchase_price")
129
+ with col3:
130
+ current_price = st.number_input("Edit Current Price", min_value=0.0, value=selected_stock['Current Price'], key="edit_portfolio_stock_current_price")
131
+ with col4:
132
+ quantity = st.number_input("Edit Quantity", min_value=0, value=selected_stock['Quantity'], key="edit_portfolio_stock_quantity")
133
+
134
+ update_button = st.form_submit_button("Update Portfolio Stock")
135
+ if update_button:
136
+ edit_portfolio_stock(selected_stock_index, name, purchase_price, current_price, quantity)
137
+
138
+ delete_button = st.button("Delete Portfolio Stock", key="delete_portfolio_stock_button")
139
+ if delete_button:
140
+ delete_portfolio_stock(selected_stock_index)
141
+
142
+ with tabs[2]:
143
+ st.header("Tax Analysis")
144
+
145
+ if st.session_state.stock_sales.shape[0] > 0:
146
+ portfolio = Portfolio()
147
+ for _, row in st.session_state.stock_sales.iterrows():
148
+ portfolio.add_stock(StockSale(row['Name'], row['Sale Price'], row['Purchase Price'], row['Quantity'], row['Holding Period (Months)']))
149
+
150
+ total_stcg, total_ltcg = portfolio.analyze_portfolio()
151
+ stcg_tax, ltcg_tax, total_tax = portfolio.apply_tax(total_stcg, total_ltcg)
152
+
153
+ stocks = []
154
+ for _, row in st.session_state.portfolio_stocks.iterrows():
155
+ stocks.append(Stock(row['Name'], row['Purchase Price'], row['Current Price'], row['Quantity']))
156
+
157
+ suggested_stocks = optimize_taxes_selling_stocks(stocks)
158
+ total_loss = calculate_total_loss(suggested_stocks)
159
+ recalculated_tax = max(0, total_tax - total_loss)
160
+
161
+ st.subheader("Analysis Results")
162
+ if total_tax > total_loss:
163
+
164
+ st.write(f"Total Short-Term Capital Gains: ₹{total_stcg:.2f}")
165
+ st.write(f"Total Long-Term Capital Gains: ₹{total_ltcg:.2f}")
166
+ st.write(f"Short-Term Capital Gains Tax: ₹{stcg_tax:.2f}")
167
+ st.write(f"Long-Term Capital Gains Tax: ₹{ltcg_tax:.2f}")
168
+ st.write(f"Total Tax Liability: ₹{total_tax:.2f}")
169
+ st.write(f"Total Loss of loss making stockes: ₹{total_loss:.2f}")
170
+
171
+ # Add a vertical spacing for better separation
172
+ st.write("\n")
173
+ st.subheader("Suggested Stocks to Sell to Offset Gains:")
174
+ # Use Streamlit's dataframe for a tabular vies
175
+ suggested_stocks_data = {
176
+ 'Name': [stock.name for stock in suggested_stocks],
177
+ 'Current Price': [stock.current_price for stock in suggested_stocks],
178
+ 'Purchase Price': [stock.purchase_price for stock in suggested_stocks]
179
+ }
180
+
181
+ st.dataframe(suggested_stocks_data)
182
+
183
+ st.write(f"Total Tax Liability before selling loss making stocks: ₹{total_tax:.2f}")
184
+ st.write(f"Adjusted Tax Liability after Selling Loss-Making Stocks and buy again: ₹{recalculated_tax:.2f}")
185
+
186
+ elif total_loss >= 0:
187
+ st.write(f"Total Short-Term Capital Gains: ₹{total_stcg:.2f}")
188
+ st.write(f"Total Long-Term Capital Gains: ₹{total_ltcg:.2f}")
189
+ st.write(f"Short-Term Capital Gains Tax: ₹{stcg_tax:.2f}")
190
+ st.write(f"Long-Term Capital Gains Tax: ₹{ltcg_tax:.2f}")
191
+ st.write(f"Total Tax Liability: ₹{total_tax:.2f}")
192
+
193
+ else:
194
+ st.write("No suggested stocks for selling to offset gains.")
195
+
196
+
197
+ # Ensure you have the 'calculate_total_loss' function implemented in utils.py
198
+ def calculate_total_loss(suggested_stocks):
199
+ total_loss = 0.0
200
+ for stock in suggested_stocks:
201
+ total_loss += (stock.purchase_price - stock.current_price) * stock.quantity
202
+ return total_loss