Skip to content

Commit

Permalink
python cache alterations made to reduce fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
eethansmith committed Dec 18, 2023
1 parent 602f181 commit e36720a
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 21 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file modified backend/.DS_Store
Binary file not shown.
Binary file not shown.
Binary file modified backend/myapp/__pycache__/graph_stock_holdings_day.cpython-38.pyc
Binary file not shown.
Binary file modified backend/myapp/__pycache__/urls.cpython-38.pyc
Binary file not shown.
89 changes: 89 additions & 0 deletions backend/myapp/graph_all_holdings_day.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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, timedelta
from collections import defaultdict

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

def get_current_shares_held(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)

current_shares = 0.0

# Calculate the current number of shares held
for transaction in transactions:
shares = float(transaction["No. of Shares"])
if transaction["Transaction Type"] == "BUY":
current_shares += shares
elif transaction["Transaction Type"] == "SELL":
current_shares -= shares

return current_shares

def get_all_holdings_day(request):
json_file_path = Path(settings.BASE_DIR) / 'data' / 'investments_data.json'

with open(json_file_path, 'r') as file:
transactions_data = json.load(file)

# Get a list of unique tickers
tickers = set(t['Ticker Symbol'] for t in transactions_data)

# Aggregated data for all stocks
aggregated_data = defaultdict(lambda: {"total_value": 0, "value_paid": 0})

# Store previous day's closing value
total_value_paid = 0

for ticker in tickers:
shares_held = get_current_shares_held(ticker)

if shares_held <= 0:
continue

stock = yf.Ticker(ticker)
today = datetime.now(tz=timezone).date()

# Find most recent market day with data
for i in range(7):
check_day = today - timedelta(days=i)
day_data = stock.history(period='1d', interval='1m', start=check_day, end=check_day + timedelta(days=1))
prev_day_data = stock.history(period="2d", interval="1d")
if not day_data.empty and len(prev_day_data) >= 2:
previous_close = prev_day_data['Close'].iloc[-2]
total_value_paid += previous_close * shares_held
break

if day_data.empty or len(prev_day_data) < 2:
continue # Skip if no data available

for time, row in day_data.iterrows():
# Add the value of this stock to the aggregated data
aggregated_data[time]["total_value"] += row['Close'] * shares_held
aggregated_data[time]["value_paid"] = total_value_paid

# Convert aggregated data to a list format suitable for JsonResponse
historical_values = [{"date": time.tz_convert(timezone).strftime('%Y-%m-%d %H:%M:%S'),
"total_value": data["total_value"],
"value_paid": data["value_paid"]}
for time, data in aggregated_data.items()]

return JsonResponse(historical_values, safe=False)
32 changes: 18 additions & 14 deletions backend/myapp/graph_stock_holdings_day.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,26 @@ def get_stock_history_day(request, ticker):
return JsonResponse({"error": "Ticker symbol is required."}, status=400)

stock = yf.Ticker(ticker)
# Get today's date and yesterday's date in the specified timezone
today = datetime.now(tz=timezone).date()
yesterday = today - timedelta(days=1)

# Fetch today's data
today_data = stock.history(period='1d', interval='1m', start=today, end=today + timedelta(days=1))
# Initialize variable to hold historical prices
historical_prices = None

if today_data.empty: # If today's data is empty, assume the market is closed
# Fetch previous day's data
historical_prices = stock.history(period='1d', interval='1m', start=yesterday, end=today)
else:
historical_prices = today_data
# Loop to find the most recent market day with data
for i in range(7): # Check up to a week back
check_day = today - timedelta(days=i)
day_data = stock.history(period='1d', interval='1m', start=check_day, end=check_day + timedelta(days=1))

if not day_data.empty:
historical_prices = day_data
break

if historical_prices is None:
return JsonResponse({"error": "No recent market data available."}, status=404)

shares_held = get_current_shares_held(ticker)
current_open_time = today_data.index[0]
current_open_time = historical_prices.index[0]

# Fetch the previous day's closing price
previous_day_data = stock.history(period="2d", interval="1d")
if len(previous_day_data) < 2:
Expand All @@ -78,8 +82,8 @@ def get_stock_history_day(request, ticker):
# Add rest of the historical values
historical_values.extend([{
"date": date.tz_convert(timezone).strftime('%Y-%m-%d %H:%M:%S'),
"value": row['Close'] * shares_held, # Current value of shares held
"value_paid": previous_close_paid # Value based on previous day's close
"value": row['Close'] * shares_held,
"value_paid": previous_close_paid
} for date, row in historical_prices.iterrows()])

return JsonResponse(historical_values, safe=False)
return JsonResponse(historical_values, safe=False)
2 changes: 2 additions & 0 deletions backend/myapp/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from .current_stock_holdings_day import get_stock_holdings_day
from .graph_stock_holdings import get_stock_history
from .graph_stock_holdings_day import get_stock_history_day
from .graph_all_holdings_day import get_all_holdings_day
from .historic_stock_holdings import get_historic_stock_holdings
from .graph_all_holdings import get_portfolio_value

Expand All @@ -11,6 +12,7 @@
path('stock_holdings_day/', get_stock_holdings_day, name='stock_holdings_day'),
path('graph_stock/<str:ticker>/', get_stock_history, name='graph_stock'),
path('graph_stock_day/<str:ticker>/', get_stock_history_day, name='graph_stock_day'),
path('graph_all_day/', get_all_holdings_day, name='graph_all_day'),
path('historic_holdings/', get_historic_stock_holdings, name='all_holdings'),
path('graph_portfolio/<int:days>/', get_portfolio_value, name='graph_portfolio'),
]
88 changes: 88 additions & 0 deletions frontend/src/AllGraphingDay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useState, useEffect } from 'react';
import { Line } from 'react-chartjs-2';
import 'chart.js/auto';
import 'chartjs-adapter-date-fns';

function AllGraphDay({ ticker, timeFrame }) {
const [stockData, setStockData] = useState([]);

useEffect(() => {
// Ensure the ticker value is included in the fetch URL
fetch(`http://localhost:8000/api/graph_all_day/`)
.then(response => response.json())
.then(data => setStockData(data))
.catch(error => console.error('Error fetching data:', error));
}, [ticker]);

const chartData = {
labels: stockData.map(data => data.date),
datasets: [
{
// Dataset for stock value
label: 'Stock Value',
data: stockData.map(data => data.value),
fill: false,
backgroundColor: 'rgba(75, 192, 192 0.1)',
borderColor: 'rgb(75, 245, 192)',
borderWidth: 0.8,
tension: 0.1,
pointRadius: 0,
hoverRadius: 0,
},
{
// Dataset for cumulative investment
label: 'Cumulative Investment',
data: stockData.map(data => data.value_paid),
fill: false,

borderColor: 'rgb(245, 245, 245)',
borderWidth: 0.75,
tension: 0.1,
pointRadius: 0,
hoverRadius: 0,
},
]
};

const chartOptions = {
responsive: true,
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false
},
},
scales: {
y: {
beginAtZero: false
},
x: {
type: 'time',
time: {
unit: 'month',
displayFormats: {
month: 'dd-MM-yy-HH:mm'
}
},
ticks: {
display: false
}
}
},
animation: {
duration: 1000 // Animation duration in milliseconds
}
};


return (
<div className="stock-graph-container">
<Line data={chartData} options={chartOptions} />
</div>
);
}

export default AllGraphDay;
2 changes: 1 addition & 1 deletion frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ h1 {
.stock-details {
display: flex;
flex-direction: column;
align-items: flex-start;
align-items: center;
color: #909090;
gap: 5px; /* Added space between info lines */
}
Expand Down
12 changes: 7 additions & 5 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import homeImage from './resources/menu-con.jpg';
import StockHoldings from './StockHoldings';
import StockGraphAll from './StockGraphingAll';
import StockGraphDay from './StockGraphingDay';
import AllGraphingDay from './AllGraphingDay';
import HistoricHoldings from './HistoricHoldings';
import TimeFrameFlip from './TimeFrameFlip';

Expand Down Expand Up @@ -72,12 +73,13 @@ function App() {
<header className="App-header">
<div className="header-content">
<div className="title-container">
<h1>{selectedStock ? `${selectedStock.name}` : 'Overall Portfolio'}</h1>
</div>
<TimeFrameFlip onTimeFrameChange={handleTimeFrameChange} currentTimeFrame={timeFrame} />
<h1>{selectedStock ? `${selectedStock.name}` : 'Overall Portfolio'}</h1>
</div>
{selectedStock && (
<div className="stock-info">
<TimeFrameFlip onTimeFrameChange={handleTimeFrameChange} currentTimeFrame={timeFrame} />
</div>
{!selectedStock && timeFrame === 'Day' && <AllGraphingDay />}
{selectedStock && (
<div className="stock-info">
<p>
Current Value: ${selectedStock.value_held.toFixed(2)}

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/StockHoldings.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function StockHoldings({ onStockSelect, timeFrame }) {
<div className="stock-holdings">
<h2>Current Stock Holdings</h2>
{holdings.map((stock, index) => (
<button key={index} className="stock-button" onClick={() => handleStockClick(stock)}>
<button key={`sh_${index}`} className="stock-button" onClick={() => handleStockClick(stock)}>
<img src={images[stock.ticker]} alt={stock.name} className="stock-image" />
<div className="stock-details">
<div className="stock-name">{stock.name}</div>
Expand Down

0 comments on commit e36720a

Please sign in to comment.