Skip to content

Commit

Permalink
setting up API communication for stock graphing
Browse files Browse the repository at this point in the history
  • Loading branch information
eethansmith committed Dec 4, 2023
1 parent 9251bee commit 38f94ce
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 79 deletions.
Binary file not shown.
Binary file modified backend/myapp/__pycache__/urls.cpython-38.pyc
Binary file not shown.
Binary file modified backend/myapp/__pycache__/views.cpython-38.pyc
Binary file not shown.
75 changes: 75 additions & 0 deletions backend/myapp/current_stock_holdings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import json
from django.http import JsonResponse
from django.conf import settings
from pathlib import Path
import yfinance as yf

def get_stock_holdings(request):
# Define the path to the JSON file
json_file_path = Path(settings.BASE_DIR) / 'data' / 'investments_data.json'

# Open the JSON file and load its content
with open(json_file_path, 'r') as file:
transactions_data = json.load(file)

# Process transactions to determine current holdings
holdings = {}
latest_average_costs = {}
for transaction in transactions_data:
ticker = transaction["Ticker Symbol"]
shares = float(transaction["No. of Shares"])
transaction_type = transaction["Transaction Type"]
avg_cost = float(transaction["Average Cost per Share USD"])


if ticker not in holdings:
holdings[ticker] = 0.0

holdings[ticker] += shares if transaction_type == "BUY" else -shares
latest_average_costs[ticker] = avg_cost # Update with the latest average cost


# Filter out stocks where holdings are zero or negative
holdings = {k: v for k, v in holdings.items() if v > 0}

# Fetch live data for remaining stocks
live_data = {}
for ticker, shares in holdings.items():
try:
stock = yf.Ticker(ticker)
stock_info = stock.info

# Determine the correct fields based on the ticker
name_field = "longName" if ticker == "VUAG.L" else "shortName"
price_field = "previousClose" if ticker == "VUAG.L" else "currentPrice"

# Fetch the relevant data
name = stock_info.get(name_field)
current_price = stock_info.get(price_field) or stock_info.get("previousClose")
average_cost = latest_average_costs[ticker]
total_investment = average_cost * shares
current_value = shares * current_price if current_price is not None else None
value_held = round((shares * current_price if current_price is not None else None),2)

profit_loss_percentage = round((((current_value - total_investment) / total_investment * 100) if current_value is not None else None),2)


live_data[ticker] = {
"ticker": ticker,
"name": name,
"shares_held": round(shares,4),
"current_price": current_price,
"value_held": value_held,
"profit_loss_percentage": profit_loss_percentage
}
except Exception as e:
print(f"Error fetching data for {ticker}: {e}")
live_data[ticker] = {
"ticker": ticker,
"error": str(e)
}

sorting_data = sorted(live_data.items(), key=lambda x: x[1].get('value_held', 0), reverse=True)
live_data = {k: v for k, v in sorting_data}

return JsonResponse(live_data)
63 changes: 63 additions & 0 deletions backend/myapp/graph_stock_holdings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import json
from django.http import JsonResponse
from django.conf import settings
from pathlib import Path
import yfinance as yf
import pytz
from datetime import datetime

# Your timezone, for example, 'UTC'
timezone = pytz.timezone('EST')

def get_stock_history(request, ticker):
if not ticker:
return JsonResponse({"error": "Ticker symbol is required."}, status=400)

# Define the path to the JSON file
json_file_path = Path(settings.BASE_DIR) / 'data' / 'investments_data.json'

# Open the JSON file and load its content
with open(json_file_path, 'r') as file:
transactions_data = json.load(file)

transactions = [t for t in transactions_data if t['Ticker Symbol'] == ticker]

if not transactions:
return JsonResponse({"error": "No transactions found for given ticker."}, status=404)

# Sort transactions by date
transactions.sort(key=lambda x: datetime.strptime(x["Date"], '%d-%m-%Y'))

# Get the first purchase date and last sale/current date
start_date = datetime.strptime(transactions[0]["Date"], '%d-%m-%Y')
end_date = datetime.now()

stock = yf.Ticker(ticker)
historical_prices = stock.history(start=start_date.strftime('%Y-%m-%d'), end=end_date.strftime('%Y-%m-%d'))

historical_values = []
current_shares = 0

# Before the loop, sort transactions by date
transactions.sort(key=lambda x: datetime.strptime(x["Date"], '%d-%m-%Y'))

for date, row in historical_prices.iterrows():
date = date.to_pydatetime().replace(tzinfo=None) # Make date timezone naive
current_shares = 0 # Reset current shares for each date

# Accumulate shares up to the current date
for transaction in transactions:
transaction_date = datetime.strptime(transaction["Date"], '%d-%m-%Y')

if transaction_date <= date:
shares = float(transaction["No. of Shares"])
if transaction["Transaction Type"] == "BUY":
current_shares += shares
elif transaction["Transaction Type"] == "SELL":
current_shares -= shares

# Calculate value for the current date
value = current_shares * row['Close']
historical_values.append({"date": date.strftime('%Y-%m-%d'), "value": value})

return JsonResponse(historical_values, safe=False)
6 changes: 4 additions & 2 deletions backend/myapp/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.urls import path
from .views import get_stock_holdings
from .current_stock_holdings import get_stock_holdings
from .graph_stock_holdings import get_stock_history

urlpatterns = [
path('stock_holdings/', get_stock_holdings, name='stock_holdings'),
]
path('graph_stock/<str:ticker>/', get_stock_history, name='graph_stock'),
]
81 changes: 4 additions & 77 deletions backend/myapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,10 @@
from django.http import JsonResponse
from django.conf import settings
from pathlib import Path
from rest_framework import viewsets
import yfinance as yf
import pytz
from datetime import datetime

# Your timezone, for example, 'UTC'
timezone = pytz.timezone('EST')

def load_transactions(request):
json_file_path = Path(settings.BASE_DIR) / 'data' / 'investments_data.json'
with open(json_file_path, 'r') as file:
data = json.load(file)
return JsonResponse(data, safe=False)

def get_stock_holdings(request):
# Define the path to the JSON file
json_file_path = Path(settings.BASE_DIR) / 'data' / 'investments_data.json'


# Open the JSON file and load its content
with open(json_file_path, 'r') as file:
transactions_data = json.load(file)

# Process transactions to determine current holdings
holdings = {}
latest_average_costs = {}
for transaction in transactions_data:
ticker = transaction["Ticker Symbol"]
shares = float(transaction["No. of Shares"])
transaction_type = transaction["Transaction Type"]
avg_cost = float(transaction["Average Cost per Share USD"])


if ticker not in holdings:
holdings[ticker] = 0.0

holdings[ticker] += shares if transaction_type == "BUY" else -shares
latest_average_costs[ticker] = avg_cost # Update with the latest average cost


# Filter out stocks where holdings are zero or negative
holdings = {k: v for k, v in holdings.items() if v > 0}

# Fetch live data for remaining stocks
live_data = {}
for ticker, shares in holdings.items():
try:
stock = yf.Ticker(ticker)
stock_info = stock.info

# Determine the correct fields based on the ticker
name_field = "longName" if ticker == "VUAG.L" else "shortName"
price_field = "previousClose" if ticker == "VUAG.L" else "currentPrice"

# Fetch the relevant data
name = stock_info.get(name_field)
current_price = stock_info.get(price_field) or stock_info.get("previousClose")
average_cost = latest_average_costs[ticker]
total_investment = average_cost * shares
current_value = shares * current_price if current_price is not None else None
value_held = round((shares * current_price if current_price is not None else None),2)

profit_loss_percentage = round((((current_value - total_investment) / total_investment * 100) if current_value is not None else None),2)


live_data[ticker] = {
"ticker": ticker,
"name": name,
"shares_held": round(shares,4),
"current_price": current_price,
"value_held": value_held,
"profit_loss_percentage": profit_loss_percentage
}
except Exception as e:
print(f"Error fetching data for {ticker}: {e}")
live_data[ticker] = {
"ticker": ticker,
"error": str(e)
}

sorting_data = sorted(live_data.items(), key=lambda x: x[1].get('value_held', 0), reverse=True)
live_data = {k: v for k, v in sorting_data}

return JsonResponse(live_data)

0 comments on commit 38f94ce

Please sign in to comment.