diff --git a/backend/myapp/__pycache__/current_stock_holdings.cpython-38.pyc b/backend/myapp/__pycache__/current_stock_holdings.cpython-38.pyc new file mode 100644 index 0000000..8b8c0bc Binary files /dev/null and b/backend/myapp/__pycache__/current_stock_holdings.cpython-38.pyc differ diff --git a/backend/myapp/__pycache__/urls.cpython-38.pyc b/backend/myapp/__pycache__/urls.cpython-38.pyc index 6e2fedb..4f1e4a3 100644 Binary files a/backend/myapp/__pycache__/urls.cpython-38.pyc and b/backend/myapp/__pycache__/urls.cpython-38.pyc differ diff --git a/backend/myapp/__pycache__/views.cpython-38.pyc b/backend/myapp/__pycache__/views.cpython-38.pyc index 798000d..4d2b3e3 100644 Binary files a/backend/myapp/__pycache__/views.cpython-38.pyc and b/backend/myapp/__pycache__/views.cpython-38.pyc differ diff --git a/backend/myapp/current_stock_holdings.py b/backend/myapp/current_stock_holdings.py new file mode 100644 index 0000000..e06b546 --- /dev/null +++ b/backend/myapp/current_stock_holdings.py @@ -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) \ No newline at end of file diff --git a/backend/myapp/graph_stock_holdings.py b/backend/myapp/graph_stock_holdings.py new file mode 100644 index 0000000..42b28f3 --- /dev/null +++ b/backend/myapp/graph_stock_holdings.py @@ -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) diff --git a/backend/myapp/urls.py b/backend/myapp/urls.py index 47c9f9c..a5074cf 100644 --- a/backend/myapp/urls.py +++ b/backend/myapp/urls.py @@ -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//', get_stock_history, name='graph_stock'), +] \ No newline at end of file diff --git a/backend/myapp/views.py b/backend/myapp/views.py index 73f81ce..6734cc9 100644 --- a/backend/myapp/views.py +++ b/backend/myapp/views.py @@ -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) \ No newline at end of file