Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create working API call for stockdata in watchlist #42

Merged
merged 8 commits into from
Jul 23, 2024
Merged
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
56 changes: 56 additions & 0 deletions backend/call_test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from celery import shared_task
import requests
import os
import django
from datetime import datetime

API_KEY = 'NBVT8WXYHNR8FKTB'
TEST_STOCK = 'MSFT'

# Set up Django environment
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cashflow.settings')
django.setup()

# Import models after setting up Django

from watchlist.models import StockData # Adjusted import path
@shared_task
def fetch_stock_data():
ticker = TEST_STOCK
response = requests.get(f'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={ticker}&apikey={API_KEY}')

if response.status_code == 200:
data = response.json().get("Global Quote")
if data:
open_price = data["02. open"]
low = data["04. low"]
high = data["03. high"]
close_price = data["05. price"]
date = data["07. latest trading day"]
change = data["09. change"]
change_percent = data["10. change percent"]

# Print the data for testing purposes
print(f"Ticker: {ticker}, Date: {date}, Open: {open_price}, Low: {low}, High: {high}, Close: {close_price}, Change: {change}, Change Percent: {change_percent}")

# Save or update the stock data in the database
stock_data, created = StockData.objects.update_or_create(
id=f'{ticker}_{date}',
defaults={
'ticker': ticker,
'close_price': close_price,
'date': date,
'open_price': open_price,
'low': low,
'high': high,
'change': change,
'change_percent': change_percent,
},
)
else:
print(f"No data found for ticker {ticker}")
else:
print(f"Failed to fetch data for ticker {ticker}, status code: {response.status_code}")

# Call the function to test
fetch_stock_data()
7 changes: 7 additions & 0 deletions backend/cashflow/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from __future__ import absolute_import, unicode_literals

# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app

__all__ = ('celery_app',)
15 changes: 15 additions & 0 deletions backend/cashflow/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# Set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cashflow.settings')

app = Celery('cashflow')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()
12 changes: 12 additions & 0 deletions backend/cashflow/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pathlib import Path
from datetime import timedelta # for simplej
import os
from celery.schedules import crontab

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Expand Down Expand Up @@ -233,3 +234,14 @@
EMAIL_HOST_PASSWORD = "dtzpryavconjxsjo"
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'

CELERY_BEAT_SCHEDULE = {
'fetch_stock_data': {
'task': 'watchlist.tasks.fetch_stock_data',
'schedule': crontab(hour=0, minute=0),
},
}

CELERY_TIMEZONE = 'UTC+8'
File renamed without changes.
6 changes: 3 additions & 3 deletions backend/insert_test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

# Example data to insert
test_data = [
{'ticker': 'AAPL', 'close_price': 150.0, 'date': datetime(2023, 7, 7)},
{'ticker': 'MSFT', 'close_price': 280.0, 'date': datetime(2023, 7, 7)},
{'ticker': 'GOOGL', 'close_price': 2700.0, 'date': datetime(2023, 7, 7)},
{'ticker': 'AAPL', 'open_price': 150.0, 'high': 150.0, 'low': 150.0, 'close_price': 150.0, 'date': "2023-07-07", 'change': 0.0, 'change_percent': '0%'},
{'ticker': 'MSFT', 'open_price': 150.0, 'high': 150.0, 'low': 150.0, 'close_price': 150.0, 'date': "2023-07-07", 'change': 0.0, 'change_percent': '0%'},
{'ticker': 'GOOGL', 'open_price': 150.0, 'high': 150.0, 'low': 150.0, 'close_price': 150.0, 'date': "2023-07-07", 'change': 0.0, 'change_percent': '0%'},
]

# Insert test data
Expand Down
Binary file modified backend/requirements.txt
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 5.0.6 on 2024-07-16 14:44

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('watchlist', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='stockdata',
name='high',
field=models.FloatField(default=0),
preserve_default=False,
),
migrations.AddField(
model_name='stockdata',
name='low',
field=models.FloatField(default=0),
preserve_default=False,
),
migrations.AddField(
model_name='stockdata',
name='open_price',
field=models.FloatField(default=0),
preserve_default=False,
),
migrations.AlterField(
model_name='stockdata',
name='date',
field=models.CharField(max_length=10),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.0.6 on 2024-07-18 15:17

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('watchlist', '0002_stockdata_high_stockdata_low_stockdata_open_price_and_more'),
]

operations = [
migrations.AddField(
model_name='stockdata',
name='change',
field=models.FloatField(default=0),
preserve_default=False,
),
migrations.AddField(
model_name='stockdata',
name='change_percent',
field=models.FloatField(default=0),
preserve_default=False,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.13 on 2024-07-21 23:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('watchlist', '0003_stockdata_change_stockdata_change_percent'),
]

operations = [
migrations.AlterField(
model_name='stockdata',
name='change_percent',
field=models.CharField(max_length=10),
),
]
7 changes: 6 additions & 1 deletion backend/watchlist/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ def create_from_json(data: dict, user_pk: int):
class StockData(models.Model):
id = models.CharField(max_length=100, primary_key=True)
ticker = models.CharField(max_length=10)
open_price = models.FloatField()
close_price = models.FloatField()
date = models.DateTimeField()
high = models.FloatField()
low = models.FloatField()
change = models.FloatField()
change_percent = models.CharField(max_length=10)
date = models.CharField(max_length=10)

def __str__(self):
return f"{self.ticker} - {self.date}"
2 changes: 1 addition & 1 deletion backend/watchlist/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ class Meta:
class StockDataSerializer(serializers.ModelSerializer):
class Meta:
model = StockData
fields = ['id', 'ticker', 'close_price', 'date']
fields = ['id', 'ticker', 'open_price', 'close_price', 'high', 'low', 'date', 'change', 'change_percent']
53 changes: 39 additions & 14 deletions backend/watchlist/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,47 @@
from datetime import datetime
from .models import StockData

API_KEY = 'your_api_key'
STOCKS = ['AAPL', 'MSFT', 'GOOGL'] # Top 25 by market cap in S&P 500
API_KEY = 'NBVT8WXYHNR8FKTB'
STOCKS = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA', 'BRK.B', 'XOM','JPM',
'JNJ', 'V', 'PG', 'MA', 'AVGO', 'CVX', 'COST',
'PEP', 'ADBE', 'NVDA', 'META', 'WMT']

@shared_task
def fetch_stock_data():
for ticker in STOCKS:
response = requests.get(f'https://api.example.com/stock/{ticker}/quote', params={'api_key': API_KEY})
data = response.json()
close_price = data['close']
date = datetime.strptime(data['date'], '%Y-%m-%dT%H:%M:%S')
response = requests.get(f'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={ticker}&apikey={API_KEY}')

if response.status_code == 200:
data = response.json().get("Global Quote")
if data:
open_price = data["02. open"]
low = data["04. low"]
high = data["03. high"]
close_price = data["05. price"]
date = data["07. latest trading day"]
change = data["09. change"]
change_percent = data["10. change percent"]

stock_data, created = StockData.objects.update_or_create(
id=f'{ticker}_{date}',
defaults={
'ticker': ticker,
'close_price': close_price,
'date': date,
},
)
# Print the data for testing purposes
print(f"Ticker: {ticker}, Date: {date}, Open: {open_price}, Low: {low}, High: {high}, Close: {close_price}, Change: {change}, Change Percent: {change_percent}")

# Save or update the stock data in the database
stock_data, created = StockData.objects.update_or_create(
id=f'{ticker}_{date}',
defaults={
'ticker': ticker,
'close_price': close_price,
'date': date,
'open_price': open_price,
'low': low,
'high': high,
'change': change,
'change_percent': change_percent,
},
)
else:
print(f"No data found for ticker {ticker}")
else:
print(f"Failed to fetch data for ticker {ticker}, status code: {response.status_code}")
# Call the function to test
fetch_stock_data()
Loading
Loading