0% found this document useful (0 votes)
11 views6 pages

Stock Analysis with Technical Indicators

The document is a Python script for analyzing stock data using various technical indicators. It includes functions to calculate indicators like EMA, WMA, RSI, MACD, Bollinger Bands, and Stochastic Oscillator, and provides a recommendation to buy, sell, or hold based on these analyses. The script allows users to input stock tickers from a predefined list and fetches historical stock prices using the yfinance library.

Uploaded by

fnmdoom1289
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views6 pages

Stock Analysis with Technical Indicators

The document is a Python script for analyzing stock data using various technical indicators. It includes functions to calculate indicators like EMA, WMA, RSI, MACD, Bollinger Bands, and Stochastic Oscillator, and provides a recommendation to buy, sell, or hold based on these analyses. The script allows users to input stock tickers from a predefined list and fetches historical stock prices using the yfinance library.

Uploaded by

fnmdoom1289
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

import math

import yfinance as yf
from [Link] import display, HTML

# Data Abstraction: List of valid stock tickers for input validation and display (student
developed)
dowstocks = ["AAPL", "MSFT", "JPM", "DIS", "BA", "GS", "IBM", "INTC", "CSCO", "VZ",
"WMT", "HD", "CVX", "MRK", "KO", "PG", "JNJ", "MMM", "AXP", "NKE",
"CAT", "TRV", "UNH", "V", "WBA", "XOM", "PFE", "RTX", "DOW", "AMGN",
"TSLA", "NVDA", "MSTR", "GOOG", "F", "AMD", "CLSK", "HOOD", "BTC-USD",
"MLGO", "PLTR", "LCID", "NIO", "SOFI", "AMZN", "AAL", "W", "CVNA", "RIOT",
"GAP", "ZETA", "SPY"]

# Helper Functions for Technical Indicators

def calculate_ema(prices, period): #steudent developed


"""Calculate Exponential Moving Average; returns None if data insufficient."""
if len(prices) < period:
return None
multiplier = 2 / (period + 1)
ema = prices[-period]
for price in prices[-period + 1:]:
ema = (price * multiplier) + (ema * (1 - multiplier))
return ema

def calculate_wma(prices, period): #student developed


"""Calculate Weighted Moving Average; returns None if data insufficient."""
if len(prices) < period:
return None
weights = list(range(1, period + 1))
weighted_sum = sum(p * w for p, w in zip(prices[-period:], weights))
return weighted_sum / sum(weights)

def calculate_rsi(prices, period=11): #(made by claude sonnet 3.7)


"""Calculate Relative Strength Index; returns None if data insufficient."""
if len(prices) < period + 1:
return None
gains = 0
losses = 0
for i in range(1, len(prices)):
diff = prices[i] - prices[i-1]
if diff > 0:
gains += diff
elif diff < 0:
losses -= diff
avg_gain = gains / period
avg_loss = losses / period
if avg_loss == 0:
return 100
rs = avg_gain / avg_loss
return 100 - (100 / (1 + rs))

def calculate_macd(prices, short_period=3, long_period=6, signal_period=2):#this was


made by grok 3
"""Calculate MACD (line, signal, histogram); returns None if data insufficient."""
if len(prices) < long_period:
return None, None, None
short_ema = calculate_ema(prices, short_period)
long_ema = calculate_ema(prices, long_period)
macd_line = short_ema - long_ema
signal_prices = prices[-signal_period:] if len(prices) >= signal_period else prices
signal_line = calculate_ema(signal_prices, signal_period) if signal_prices else None
histogram = macd_line - signal_line if signal_line else None
return macd_line, signal_line, histogram

def calculate_bollinger_bands(prices, period=10, std_dev=2): #This was made by grok


ai
"""Calculate Bollinger Bands (upper, middle, lower); returns None if data
insufficient."""
if len(prices) < period:
return None, None, None
sma = sum(prices[-period:]) / period
squared_diff_sum = 0
for price in prices[-period:]:
squared_diff_sum += (price - sma) ** 2
std = [Link](squared_diff_sum / period)
upper_band = sma + (std_dev * std)
lower_band = sma - (std_dev * std)
return upper_band, sma, lower_band
def calculate_stochastic(prices, k_period=5, d_period=3): #(This was made by grok ai)
"""Calculate Stochastic Oscillator (%K, %D); returns None if data insufficient."""
if len(prices) < k_period + d_period - 1:
return None, None
k_values = []
for i in range(len(prices) - k_period + 1):
window = prices[i:i + k_period]
current_close = window[-1]
lowest_low = min(window)
highest_high = max(window)
k_value = 50 if highest_high - lowest_low == 0 else 100 * ((current_close -
lowest_low) / (highest_high - lowest_low))
k_values.append(k_value)
k_value = k_values[-1]
d_value = sum(k_values[-d_period:]) / d_period if len(k_values) >= d_period else
None
return k_value, d_value

# Student-Developed Procedure for Stock Analysis (student developed)


def analyze_stock(ticker, prices):
"""Analyze stock data and return a Buy/Sell/Hold recommendation."""
# Sequencing: Calculate SMA first
period = 4
sma_3 = 0
for price in prices[-period:]: # Iteration: Loop over last 4 prices
sma_3 += price
sma_3 /= period

# Calculate technical indicators


ema_3 = calculate_ema(prices, 3)
wma_3 = calculate_wma(prices, 3)
rsi = calculate_rsi(prices, 11)
macd_line, signal_line, _ = calculate_macd(prices, 3, 6, 2)
upper_band, bb_middle, lower_band = calculate_bollinger_bands(prices, 10, 2)
stoch_k, stoch_d = calculate_stochastic(prices, 5, 3)

# Selection: Evaluate signals


current_price = prices[-1]
buy_signals = 0
sell_signals = 0
if current_price > sma_3:
buy_signals += 1
elif current_price < sma_3:
sell_signals += 1

if ema_3 and current_price > ema_3:


buy_signals += 1
elif ema_3 and current_price < ema_3:
sell_signals += 1

if wma_3 and current_price > wma_3:


buy_signals += 1
elif wma_3 and current_price < wma_3:
sell_signals += 1

if rsi is not None:


if rsi < 30:
buy_signals += 1
elif rsi > 70:
sell_signals += 1

if macd_line is not None and signal_line is not None:


if macd_line > signal_line:
buy_signals += 1
elif macd_line < signal_line:
sell_signals += 1

if upper_band is not None and lower_band is not None:


if current_price < lower_band:
buy_signals += 1
elif current_price > upper_band:
sell_signals += 1

if stoch_k is not None:


if stoch_k < 20:
buy_signals += 1
elif stoch_k > 80:
sell_signals += 1
if stoch_d is not None:
if stoch_d < 20:
buy_signals += 1
elif stoch_d > 80:
sell_signals += 1

# Format output
rsi_display = f"{rsi:.2f}" if rsi is not None else "N/A"
macd_display = f"{macd_line:.2f}" if macd_line is not None else "N/A"
bb_display = f"{bb_middle:.2f} [{lower_band:.2f}, {upper_band:.2f}]" if bb_middle is
not None else "N/A"
stoch_display = f"K:{stoch_k:.2f}, D:{stoch_d:.2f}" if stoch_k is not None and stoch_d
is not None else f"K:{stoch_k:.2f}" if stoch_k is not None else "N/A"

# Selection: Determine recommendation


if buy_signals >= 4:
return f"{ticker}: Buy (SMA: {sma_3:.2f}, EMA: {ema_3:.2f}, WMA: {wma_3:.2f},
RSI: {rsi_display}, MACD: {macd_display}, BB: {bb_display}, Stoch: {stoch_display})"
elif sell_signals >= 4:
return f"{ticker}: Sell (SMA: {sma_3:.2f}, EMA: {ema_3:.2f}, WMA: {wma_3:.2f},
RSI: {rsi_display}, MACD: {macd_display}, BB: {bb_display}, Stoch: {stoch_display})"
else:
return f"{ticker}: Hold (SMA: {sma_3:.2f}, EMA: {ema_3:.2f}, WMA: {wma_3:.2f},
RSI: {rsi_display}, MACD: {macd_display}, BB: {bb_display}, Stoch: {stoch_display})"

# Utility Function for Consistent Output

def print_html(text):
"""Display text in white on black background in Colab."""
display(HTML(f"<p style='color:white; background-color:black;'>{text}</p>"))

# Main Program (This was made by the student)

print_html("Warning! This is not meant to be used for financial advice; any decisions
made by this program do not make the author responsible for any losses or gains.")
print_html("Welcome to the Dow Jones Stock Analyzer")
print_html("These are the available stocks that you can choose from: " + ",
".join(dowstocks))
stock_choices = []
print("Enter stock tickers below (type 'EXODIA' to quit):")
while True:
stock_choice = input().upper()
stock_choices.append(stock_choice)

if stock_choice == "EXODIA":
print_html("Program terminated.")
break

if stock_choice not in dowstocks:


print_html("Invalid ticker. Please select from the list above.")
continue

try:
stock = [Link](stock_choice)
hist = [Link](start="2005-01-01", end="2025-03-01", interval="1mo")
if [Link]:
print_html(f"No data available for {stock_choice}. Please try another ticker.")
continue
prices = hist['Close'].tolist()
if len(prices) < 12:
print_html(f"Insufficient data for {stock_choice}. At least 12 months required.")
continue

result = analyze_stock(stock_choice, prices)


print_html(result)
except Exception as e:
print_html(f"Error fetching data for {stock_choice}: {e}")

# Acknowledgment
# Assisted by Grok (xAI) to fix ValueError in f-string formatting, debug TypeError in RSI,
# add iteration to analyze_stock, integrate yfinance for accurate closing prices, and
update
# calculate_stochastic for full %K and %D calculation per user request.

You might also like