|
import requests |
|
from fastapi import FastAPI, Query |
|
from fastapi.responses import FileResponse |
|
import matplotlib.pyplot as plt |
|
from datetime import datetime, timedelta |
|
import pandas as pd |
|
from sklearn.linear_model import LinearRegression |
|
from sklearn.preprocessing import StandardScaler |
|
from fastapi.middleware.cors import CORSMiddleware |
|
import uvicorn |
|
from fastapi.responses import HTMLResponse |
|
|
|
app = FastAPI() |
|
|
|
|
|
origins = [ |
|
"*", |
|
] |
|
|
|
app.add_middleware( |
|
CORSMiddleware, |
|
allow_origins=origins, |
|
allow_credentials=True, |
|
allow_methods=["*"], |
|
allow_headers=["*"], |
|
) |
|
|
|
|
|
API_KEY = 'KD8IWCXSRU2EB7ST' |
|
STOCK_SYMBOL = 'AAPL' |
|
API_URL = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={STOCK_SYMBOL}&apikey={API_KEY}" |
|
|
|
|
|
def fetch_stock_data(symbol): |
|
url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}&apikey={API_KEY}" |
|
response = requests.get(url) |
|
data = response.json() |
|
return data['Time Series (Daily)'] |
|
|
|
|
|
def fetch_and_update(symbol=STOCK_SYMBOL, graph_type="line"): |
|
daily_data = fetch_stock_data(symbol) |
|
|
|
dates = [] |
|
close_prices = [] |
|
for date, daily_info in sorted(daily_data.items()): |
|
dates.append(datetime.strptime(date, '%Y-%m-%d')) |
|
close_prices.append(float(daily_info['4. close'])) |
|
|
|
plt.figure(figsize=(14, 7)) |
|
|
|
if graph_type == "line": |
|
plt.plot(dates, close_prices, marker='o', linestyle='-') |
|
elif graph_type == "bar": |
|
plt.bar(dates, close_prices) |
|
elif graph_type == "scatter": |
|
plt.scatter(dates, close_prices) |
|
elif graph_type == "buy_sell": |
|
stock_data = pd.DataFrame({'Date': dates, 'Close': close_prices}) |
|
stock_data['Short_MA'] = stock_data['Close'].rolling(window=40).mean() |
|
stock_data['Long_MA'] = stock_data['Close'].rolling(window=100).mean() |
|
|
|
buy_signals = stock_data[(stock_data['Short_MA'] > stock_data['Long_MA']) & (stock_data['Short_MA'].shift(1) <= stock_data['Long_MA'].shift(1))].index |
|
sell_signals = stock_data[(stock_data['Short_MA'] < stock_data['Long_MA']) & (stock_data['Short_MA'].shift(1) >= stock_data['Long_MA'].shift(1))].index |
|
|
|
plt.plot(stock_data['Date'], stock_data['Close'], label='Closing Price', alpha=0.5) |
|
plt.plot(stock_data['Date'], stock_data['Short_MA'], label='40-Day Moving Average', alpha=0.75) |
|
plt.plot(stock_data['Date'], stock_data['Long_MA'], label='100-Day Moving Average', alpha=0.75) |
|
plt.scatter(stock_data.loc[buy_signals]['Date'], stock_data.loc[buy_signals]['Close'], marker='^', color='g', label='Buy Signal', alpha=1) |
|
plt.scatter(stock_data.loc[sell_signals]['Date'], stock_data.loc[sell_signals]['Close'], marker='v', color='r', label='Sell Signal', alpha=1) |
|
|
|
plt.title(f'{symbol} Stock Prices Over Time') |
|
plt.xlabel('Date') |
|
plt.ylabel('Close Price ($)') |
|
plt.gcf().autofmt_xdate() |
|
plt.legend() |
|
plt.savefig("stock.png") |
|
plt.close() |
|
return dates, close_prices |
|
|
|
|
|
def preprocess_data(dates, close_prices): |
|
df = pd.DataFrame({'Date': dates, 'Close': close_prices}) |
|
df['Date_ordinal'] = pd.to_datetime(df['Date']).apply(lambda date: date.toordinal()) |
|
|
|
|
|
df.fillna(method='ffill', inplace=True) |
|
df.fillna(method='bfill', inplace=True) |
|
|
|
|
|
scaler = StandardScaler() |
|
df['Close_scaled'] = scaler.fit_transform(df[['Close']]) |
|
|
|
return df, scaler |
|
|
|
|
|
def predict_stock_prices(dates, close_prices, interval_days=7): |
|
df, scaler = preprocess_data(dates, close_prices) |
|
|
|
model = LinearRegression() |
|
model.fit(df[['Date_ordinal']], df['Close_scaled']) |
|
|
|
last_date = df['Date'].max() |
|
future_dates = [last_date + timedelta(days=i) for i in range(1, interval_days+1)] |
|
future_ordinal = [date.toordinal() for date in future_dates] |
|
scaled_predictions = model.predict(pd.DataFrame(future_ordinal, columns=['Date_ordinal'])) |
|
|
|
predictions = scaler.inverse_transform(scaled_predictions.reshape(-1, 1)).flatten() |
|
|
|
return future_dates, predictions |
|
|
|
|
|
@app.get("/", response_class=HTMLResponse) |
|
async def read_root(): |
|
html= open("index.html","r") |
|
return HTMLResponse(content=html.read()) |
|
|
|
|
|
@app.get("/graph") |
|
async def get_graph(symbol: str = STOCK_SYMBOL, graph_type: str = Query("line", enum=["line", "bar", "scatter", "buy_sell"])): |
|
dates, close_prices = fetch_and_update(symbol, graph_type) |
|
return FileResponse("stock.png") |
|
|
|
|
|
@app.get("/predict") |
|
async def predict(symbol: str = STOCK_SYMBOL, interval: int = 7): |
|
dates, close_prices = fetch_and_update(symbol) |
|
future_dates, predictions = predict_stock_prices(dates, close_prices, interval) |
|
|
|
prediction_data = {str(date): float(pred) for date, pred in zip(future_dates, predictions)} |
|
return prediction_data |
|
|
|
|
|
|
|
|
|
|