From c7a08aba968e935e76b024834321d48bca072105 Mon Sep 17 00:00:00 2001 From: GonzaloHD Date: Mon, 15 Jun 2026 07:02:22 +0100 Subject: [PATCH] Start project --- .gitignore | 4 ++++ README.md | 13 +++++++++-- requirements.txt | 3 +++ stock_analysis.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 requirements.txt create mode 100644 stock_analysis.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf5a097 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.env +__pycache__/ +.venv +data/ \ No newline at end of file diff --git a/README.md b/README.md index fdc3cc6..e0c33d0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ -# stock-finance-analyzer +# Stock Finance Analyzer -A small Python finance project that fetches historical stock prices from Alpaca and calculates some indicators. \ No newline at end of file +A small Python finance project that fetches historical stock prices from Alpaca and calculates: + +- highest close price +- lowest close price +- average close price +- daily returns +- average return +- 3-day moving average + +This project was built as part of my Python/pandas finance learning path. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..459034f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pandas +python-dotenv +alpaca-py \ No newline at end of file diff --git a/stock_analysis.py b/stock_analysis.py new file mode 100644 index 0000000..32375fd --- /dev/null +++ b/stock_analysis.py @@ -0,0 +1,58 @@ +from datetime import datetime +import os + +import pandas as pd +from dotenv import load_dotenv + +from alpaca.data.historical import StockHistoricalDataClient +from alpaca.data.requests import StockBarsRequest +from alpaca.data.timeframe import TimeFrame + + +load_dotenv() + +API_KEY = os.getenv("ALPACA_API_KEY") +SECRET_KEY = os.getenv("ALPACA_SECRET_KEY") + + +def fetch_stock_data(symbol, start_date, end_date): + client = StockHistoricalDataClient(API_KEY, SECRET_KEY) + + request = StockBarsRequest( + symbol_or_symbols=symbol, + timeframe=TimeFrame.Day, + start=datetime.fromisoformat(start_date), + end=datetime.fromisoformat(end_date), + ) + + bars = client.get_stock_bars(request) + df = bars.df.reset_index() + + return df + + +def analyze_stock(df): + df["Return"] = df["close"].pct_change() + df["MA_3"] = df["close"].rolling(window=3).mean() + + print("\nFirst rows:") + print(df.head()) + + print("\nStock analysis:") + print(f"Highest price: {df['close'].max():.2f}") + print(f"Lowest price: {df['close'].min():.2f}") + print(f"Average price: {df['close'].mean():.2f}") + print(f"Average return: {df['Return'].mean():.4f}") + + print("\nClose, Return, MA_3:") + print(df[["timestamp", "close", "Return", "MA_3"]]) + + +if __name__ == "__main__": + symbol = input("Enter stock symbol, for example AAPL: ").upper() + + start_date = input("Start date YYYY-MM-DD: ") + end_date = input("End date YYYY-MM-DD: ") + + df = fetch_stock_data(symbol, start_date, end_date) + analyze_stock(df) \ No newline at end of file