Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5829,9 +5829,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"display_name": "streamlit_apps",
"language": "python",
"name": "python2"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -5843,7 +5843,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.13"
"version": "3.12.2"
}
},
"nbformat": 4,
Expand Down
8 changes: 8 additions & 0 deletions Investment_Portfolio_App.code-workspace
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}
Binary file added New Sheet.xlsx
Binary file not shown.
Binary file added New_Sheet.xlsx
Binary file not shown.
Binary file removed Sample stocks acquisition dates_costs.xlsx
Binary file not shown.
149 changes: 149 additions & 0 deletions Updated App.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Import initial libraries

import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
import yfinance as yf


from plotly import __version__
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

import plotly.graph_objs as go

print(__version__) # requires version >= 1.9.0

init_notebook_mode(connected=True)

filepath = "./New Sheet.xlsx"
print("filepath: ", filepath)
# Load the entire Excel file
xls = pd.ExcelFile(filepath)

# Load all sheet names
sheet_names = xls.sheet_names
print("sheet_names: ", sheet_names)
# Load all sheets into a dictionary of DataFrames
dfs = {sheet: pd.read_excel(xls, sheet) for sheet in sheet_names}

# Convert the 'Transaction Date' column to datetime format (only year, month, day) in the 'transactions' DataFrame
dfs['Transactions']['Transaction Date'] = pd.to_datetime(dfs['Transactions']['Transaction Date']).dt.date

# Get unique tickers from the 'Summary' sheet
tickers = dfs['Summary']['Ticker'].unique().tolist() # Convert numpy array to list

# Fetch today's data for all tickers
data = yf.download(tickers, period='1d')

# Convert 'Adj Close' DataFrame to a Series
adj_close_series = data['Adj Close'].squeeze()

# Update the 'Price Today' column in the 'Summary' DataFrame
dfs['Summary']['Price Today'] = dfs['Summary']['Ticker'].map(adj_close_series).round(2)

# Update the 'Current Value' column in the 'Summary' DataFrame
dfs['Summary']['Current Value'] = dfs['Summary']['Quantity'] * dfs['Summary']['Price Today'].round(3)

# Update the 'Transaction Total' column in the 'Transactions' DataFrame
dfs['Transactions']['Transaction Total'] = dfs['Transactions']['Shares'] * dfs['Transactions']['Cost Per Share']

# Copy the 'Ticker' column from the 'Transactions' DataFrame to the 'Summary' DataFrame
dfs['Summary']['Ticker'] = dfs['Transactions']['Ticker']

# Calculate the total quantity for each ticker
quantity_series = dfs['Transactions'].groupby(['Ticker', 'Type'])['Shares'].sum().unstack().fillna(0)
quantity_series['Total'] = quantity_series['Buy'] - quantity_series['Sell']

# Update the 'Quantity' column in the 'Summary' DataFrame
dfs['Summary'] = dfs['Summary'].set_index('Ticker')
dfs['Summary']['Quantity'] = quantity_series['Total']
dfs['Summary'] = dfs['Summary'].reset_index()

# Calculate the total realized sales for each ticker
realized_sales_series = dfs['Transactions'][dfs['Transactions']['Type'] == 'Sell'].groupby('Ticker')['Transaction Total'].sum()

# Update the 'Realized Sales' column in the 'Summary' DataFrame
dfs['Summary'] = dfs['Summary'].set_index('Ticker')
dfs['Summary']['Realized Sales'] = realized_sales_series
dfs['Summary'] = dfs['Summary'].reset_index()

# Sort the 'Transactions' DataFrame by date
dfs['Transactions'] = dfs['Transactions'].sort_values('Transaction Date')

cost_basis_df = pd.DataFrame(columns=['Ticker', 'Shares', 'Transaction Total'])

# Initialize a Series to hold the profit for each ticker
profit_series = pd.Series(dtype='float64')

# Iterate over the sorted 'Transactions' DataFrame
for idx, row in dfs['Transactions'].iterrows():
if row['Type'] == 'Buy':
# Add the shares to the cost basis DataFrame
cost_basis_df.loc[len(cost_basis_df)] = row[['Ticker', 'Shares', 'Transaction Total']]
elif row['Type'] == 'Sell':
# Subtract the shares from the cost basis DataFrame in the order they were added (FIFO)
sell_shares = row['Shares']
sell_ticker = row['Ticker']
sell_price = row['Transaction Total'] / sell_shares
profit = 0
for i, cost_row in cost_basis_df[cost_basis_df['Ticker'] == sell_ticker].iterrows():
if sell_shares <= 0:
break
shares_to_sell = min(sell_shares, cost_row['Shares'])
profit += shares_to_sell * (sell_price - (cost_row['Transaction Total'] / cost_row['Shares']))
sell_shares -= shares_to_sell
cost_basis_df.loc[i, 'Shares'] -= shares_to_sell
cost_basis_df = cost_basis_df[cost_basis_df['Shares'] > 0]
profit_series[sell_ticker] = profit_series.get(sell_ticker, 0) + profit

# Initialize 'Cost Basis' column in the 'Summary' DataFrame
dfs['Summary']['Cost Basis'] = 0

# Convert 'Cost Basis', 'Realized Profit' and 'Unrealized Profit' to float
for column in ['Cost Basis', 'Realized Profit', 'Unrealized Profit']:
dfs['Summary'][column] = dfs['Summary'][column].astype(float)

# Create a dictionary to hold the cost basis and shares of each ticker
cost_basis_dict = {ticker: [] for ticker in dfs['Summary']['Ticker'].unique()}

# Iterate over the 'Transactions' DataFrame
for idx, row in dfs['Transactions'].iterrows():
if row['Type'] == 'Buy':
# Add the transaction total and shares to the cost basis dictionary for the corresponding ticker
cost_basis_dict[row['Ticker']].append((row['Transaction Total'], row['Shares']))
elif row['Type'] == 'Sell':
# Subtract the cost basis of the sold shares from the cost basis dictionary for the corresponding ticker
sell_shares = row['Shares']
while sell_shares > 0 and cost_basis_dict[row['Ticker']]:
buy_total, buy_shares = cost_basis_dict[row['Ticker']][0]
if buy_shares > sell_shares:
cost_basis_dict[row['Ticker']][0] = (buy_total * (buy_shares - sell_shares) / buy_shares, buy_shares - sell_shares)
sell_shares = 0
else:
sell_shares -= buy_shares
cost_basis_dict[row['Ticker']].pop(0)

# Update the 'Cost Basis' column in the 'Summary' DataFrame
for ticker in dfs['Summary']['Ticker'].unique():
dfs['Summary'].loc[dfs['Summary']['Ticker'] == ticker, 'Cost Basis'] = sum(total for total, shares in cost_basis_dict[ticker])


# Update the 'Realized Profit' column in the 'Summary' DataFrame
dfs['Summary'] = dfs['Summary'].set_index('Ticker')
dfs['Summary']['Realized Profit'] = profit_series
dfs['Summary'] = dfs['Summary'].reset_index()

# Calculate 'Unrealized Profit' for each ticker
dfs['Summary']['Unrealized Profit'] = dfs['Summary']['Current Value'] - dfs['Summary']['Cost Basis']

# Round 'Cost Basis', 'Realized Profit' and 'Unrealized Profit' to 2 decimal places
for column in ['Cost Basis', 'Realized Profit', 'Unrealized Profit']:
dfs['Summary'][column] = dfs['Summary'][column].round(2)

# Write all DataFrames back to the Excel file
with pd.ExcelWriter(filepath, engine='openpyxl') as writer:
for sheet, df in dfs.items():
df.to_excel(writer, sheet_name=sheet, index=False)


Binary file added images/NTAI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 134 additions & 0 deletions investment_portfoli_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
"""
Based on the Streamlit Handover Delays Dashboard

Created on Tue Apr 16 2024
@author: JL

"""
import streamlit as st
import time
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
import subprocess
# import yfinance as yf

st.set_page_config(page_title='Investment Portfolio App', layout='wide', page_icon=':ambulance:')

#this is the header


# t1, t2 = st.columns((0.07,1))
t1, t2 = st.columns((0.08,1))

t1.image('images/NTAI.png', width = 120)
t2.title("Networking Technology Academy Institute:")
t2.title("\n Personal Investment Portfolio Report")
t2.markdown(" **tel:** 617-123-4567 **| website:** https://www.networktechnologyacademy.org **| email:** xyz@ntai.com")

dataFile = "New Sheet.xlsx"

## Data

with st.spinner('Updating Report...'):

#Metrics setting and rendering
subprocess.call(["python", "Investment_Portfolio_App.py"])
invstr_df = pd.read_excel(dataFile,sheet_name = 'Investors')
invstr = st.selectbox('Choose Investor', invstr_df, help = 'Filter report to show only one investor', index = 0)
subprocess.call(["python", "Investment_Portfolio_App.py"])
# Current Investment Table
cw1, cw2 = st.columns((2.7, 2.5))
# cwdf = pd.read_excel(dataFile,sheet_name = 'All')
if invstr == 'All':
cwdf = pd.read_excel(dataFile,sheet_name = 'Summary')
elif invstr != 'All':
print("inverstor selected is: ", invstr)
cwdf = pd.read_excel(dataFile,sheet_name = invstr)


fig = go.Figure(
data = [go.Table (columnorder = [0,1,2,3,4,5,6,7], columnwidth = [10,20,20,20,20,20,20,20],
header = dict(
values = list(cwdf.columns),
font=dict(size=12, color = 'white'),
fill_color = '#264653',
align = 'center',
height=20
)
, cells = dict(
values = [cwdf[K].tolist() for K in cwdf.columns],
font=dict(size=12),
align = 'center',
fill_color='#F0F2F6',
height=20))])

fig.update_layout(title_text="Summary",title_font_color = '#264653',title_x=0,margin= dict(l=0,r=10,b=10,t=30), height=480)

cw1.plotly_chart(fig, use_container_width=True)

cwdf = pd.read_excel(dataFile,sheet_name = 'Transactions')
if invstr == 'All':
cwdf = cwdf
elif invstr != 'All':
cwdf = cwdf[cwdf['Investor']==invstr]


fig = go.Figure(
data = [go.Table (columnorder = [0,1,2,3,4,5,6,7], columnwidth = [25,20,20,20,20,20,20,20],
header = dict(
values = list(cwdf.columns),
font=dict(size=12, color = 'white'),
fill_color = '#264653',
align = 'center',
height=20
)
, cells = dict(
values = [cwdf[K].tolist() for K in cwdf.columns],
font=dict(size=12),
align = 'left',
fill_color='#F0F2F6',
height=20))])

fig.update_layout(title_text="Transactions",title_font_color = '#264653',title_x=0,margin= dict(l=0,r=10,b=10,t=30), height=480)

cw2.plotly_chart(fig, use_container_width=True)


with st.spinner('Report updated!'):
time.sleep(1)

# Assume we have a DataFrame
# df = pd.DataFrame({
# 'A': [1, 2, 3, 4, 5],
# 'B': [10, 20, 30, 40, 50]
# })

# row_number = st.number_input('Input row number', min_value=0, max_value=len(df)-1, format="%i")
# column_name = st.selectbox('Select column', df.columns)
# new_value = st.number_input('Input new value', value=df.loc[row_number, column_name])

# if st.button('Update Data'):
# df.loc[row_number, column_name] = new_value
# st.write(df)


# Contact Form

with st.expander("Contact us"):
with st.form(key='contact', clear_on_submit=True):

email = st.text_input('Contact Email')
st.text_area("Query","Please fill in all the information or we may not be able to process your request")

submit_button = st.form_submit_button(label='Send Information')










Loading