youfinance / macd_prices.py
CHITTAMURUNIKHIL's picture
updating app.py files
d4f51ad verified
import streamlit as st
import yfinance as yf
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Conv1D, MaxPooling1D, Flatten
def load_and_display_macd(ticker1, ticker2, user_inputs):
"""
Fetches historical data, calculates MACD and moving averages based on user input,
trains LSTM-CNN models (for each ticker), and displays charts and predictions.
Args:
ticker1 (str): First ticker symbol.
ticker2 (str): Second ticker symbol.
user_inputs (dict): Dictionary containing user-specified parameters
- price_column (str): "High", "Low", "Close", or "Open" (default: "Close")
- ema_fast (int): Span for fast EMA (default: 12)
- ema_slow (int): Span for slow EMA (default: 26)
- signal_span (int): Span for signal EMA (default: 9)
"""
try:
data1 = yf.download(ticker1, period="3mo", interval="1h")
data2 = yf.download(ticker2, period="3mo", interval="1h")
except Exception as e:
st.error(f"Error fetching data: {e}")
return
# Get user-specified parameters (with defaults)
price_column = user_inputs.get("price_column", "Close")
ema_fast = user_inputs.get("ema_fast", 12)
ema_slow = user_inputs.get("ema_slow", 26)
signal_span = user_inputs.get("signal_span", 9)
# Calculate MACD and Signal based on user input
data1['ema_fast'] = data1[price_column].ewm(span=ema_fast, adjust=False).mean()
data1['ema_slow'] = data1[price_column].ewm(span=ema_slow, adjust=False).mean()
data1['MACD'] = data1['ema_fast'] - data1['ema_slow']
data1['Signal'] = data1['MACD'].ewm(span=signal_span, adjust=False).mean()
data1['Histogram'] = data1['MACD'] - data1['Signal']
data2['ema_fast'] = data2[price_column].ewm(span=ema_fast, adjust=False).mean()
data2['ema_slow'] = data2[price_column].ewm(span=ema_slow, adjust=False).mean()
data2['MACD'] = data2['ema_fast'] - data2['ema_slow']
data2['Signal'] = data2['MACD'].ewm(span=signal_span, adjust=False).mean()
data2['Histogram'] = data1['MACD'] - data2['Signal']
# Create candlestick charts with EMAs
fig1_candlestick = go.Figure()
fig1_candlestick.add_trace(go.Candlestick(x=data1.index,
open=data1['Open'],
high=data1['High'],
low=data1['Low'],
close=data1['Close'],
name=f'{ticker1} Candlestick'))
fig1_candlestick.add_trace(go.Scatter(x=data1.index, y=data1['ema_fast'], name=f'{ticker1} {ema_fast}-EMA', line=dict(color='red')))
fig1_candlestick.add_trace(go.Scatter(x=data1.index, y=data1['ema_slow'], name=f'{ticker1} {ema_slow}-EMA', line=dict(color='blue')))
fig1_candlestick.update_layout(title=f'{ticker1} Candlestick Chart with EMAs')
fig2_candlestick = go.Figure()
fig2_candlestick.add_trace(go.Candlestick(x=data2.index,
open=data2['Open'],
high=data2['High'],
low=data2['Low'],
close=data2['Close'],
name=f'{ticker2} Candlestick'))
fig2_candlestick.add_trace(go.Scatter(x=data2.index, y=data2['ema_fast'], name=f'{ticker2} {ema_fast}-EMA', line=dict(color='red')))
fig2_candlestick.add_trace(go.Scatter(x=data2.index, y=data2['ema_slow'], name=f'{ticker2} {ema_slow}-EMA', line=dict(color='blue')))
fig2_candlestick.update_layout(title=f'{ticker2} Candlestick Chart with EMAs')
# Create line chart for MACD and Signal
fig1_macd = go.Figure()
fig1_macd.add_trace(go.Histogram(x=data1['Histogram'], name=f'{ticker1} MACD Histogram', opacity=0.5))
fig1_macd.add_trace(go.Scatter(x=data1.index, y=data1['MACD'], name=f'{ticker1} MACD', line=dict(color='red')))
fig1_macd.add_trace(go.Scatter(x=data1.index, y=data1['Signal'], name=f'{ticker1} Signal', line=dict(color='green')))
fig1_macd.update_layout(title=f'{ticker1} MACD and Signal & Histogram')
fig2_macd = go.Figure()
fig2_macd.add_trace(go.Histogram(x=data2['Histogram'], name=f'{ticker2} MACD Histogram', opacity=0.5))
fig2_macd.add_trace(go.Scatter(x=data2.index, y=data2['MACD'], name=f'{ticker2} MACD', line=dict(color='red')))
fig2_macd.add_trace(go.Scatter(x=data2.index, y=data2['Signal'], name=f'{ticker2} Signal', line=dict(color='green')))
fig2_macd.update_layout(title=f'{ticker2} MACD and Signal & Histogram')
# Display charts
col1, col2 = st.columns(2)
with col1:
st.plotly_chart(fig1_candlestick)
st.plotly_chart(fig1_macd)
with col2:
st.plotly_chart(fig2_candlestick)
st.plotly_chart(fig2_macd)
# Create features and target for training
features_1 = data1[['ema_fast', 'ema_slow', 'MACD', 'Signal']]
target_1 = data1[price_column]
features_2 = data2[['ema_fast', 'ema_slow', 'MACD', 'Signal']]
target_2 = data2[price_column]
# Split data into training and testing sets (80/20 split)
train_size_1 = int(len(data1) * 0.8)
train_data_1, test_data_1 = features_1.iloc[:train_size_1], features_1.iloc[train_size_1:]
train_target_1, test_target_1 = target_1.iloc[:train_size_1], target_1.iloc[train_size_1:]
train_size_2 = int(len(data2) * 0.8)
train_data_2, test_data_2 = features_2.iloc[:train_size_2], features_2.iloc[train_size_2:]
train_target_2, test_target_2 = target_2.iloc[:train_size_2], target_2.iloc[train_size_2:]
# Standardize data (using StandardScaler)
scaler = StandardScaler()
scaled_train_data_1 = scaler.fit_transform(train_data_1)
scaled_test_data_1 = scaler.transform(test_data_1)
scaled_train_data_2 = scaler.fit_transform(train_data_2)
scaled_test_data_2 = scaler.transform(test_data_2)
# Reshape data for LSTM-CNN input (samples, time steps, features)
train_data_reshaped_1 = scaled_train_data_1.reshape(train_data_1.shape[0], train_data_1.shape[1], 1)
test_data_reshaped_1 = scaled_test_data_1.reshape(test_data_1.shape[0], test_data_1.shape[1], 1)
train_data_reshaped_2 = scaled_train_data_2.reshape(train_data_2.shape[0], train_data_2.shape[1], 1)
test_data_reshaped_2 = scaled_test_data_2.reshape(test_data_2.shape[0], test_data_2.shape[1], 1)
# Create LSTM-CNN models
model1 = Sequential()
model1.add(Conv1D(filters=32, kernel_size=3, activation='relu', input_shape=(train_data_reshaped_1.shape[1], 1)))
model1.add(MaxPooling1D(pool_size=2))
model1.add(LSTM(50, return_sequences=True))
model1.add(LSTM(50))
# Add a Flatten layer before the Dense layer
model1.add(Flatten())
model1.add(Dense(features_1.shape[1])) # Use the number of features from training data
model1.compile(loss='mse', optimizer='adam')
model2 = Sequential()
model2.add(Conv1D(filters=32, kernel_size=3, activation='relu', input_shape=(train_data_reshaped_2.shape[1], 1)))
model2.add(MaxPooling1D(pool_size=2))
model2.add(LSTM(50, return_sequences=True))
model2.add(LSTM(50))
model2.add(Flatten())
model2.add(Dense(features_2.shape[1])) # Use the number of features from training data
model2.compile(loss='mse', optimizer='adam')
# Train the models
model1.fit(train_data_reshaped_1, train_target_1, epochs=50, batch_size=32, verbose=1)
model2.fit(train_data_reshaped_2, train_target_2, epochs=50, batch_size=32, verbose=1)
# Make predictions
predictions_1 = model1.predict(test_data_reshaped_1)
predictions_2 = model2.predict(test_data_reshaped_2)
# Inverse transform predictions
predictions_1 = scaler.inverse_transform(predictions_1)
predictions_2 = scaler.inverse_transform(predictions_2)
# Append the predicted prices to the lists
last_prediction_1 = predictions_1[-1].reshape(1, -1)
predictions_1 = np.concatenate((predictions_1, last_prediction_1), axis=0)
last_prediction_2 = predictions_2[-1].reshape(1, -1)
predictions_2 = np.concatenate((predictions_2, last_prediction_2), axis=0)
# Update data for the next day's prediction
# Note: This part might need adjustment based on your specific data handling and prediction logic
# Here, we simply append the last prediction to the existing data
# In a real-world scenario, you might need to shift the data and handle windows more carefully
# Create a DataFrame for predicted prices
prediction_df = pd.DataFrame({'Predicted Price (' + ticker1 + ')': predictions_1[:, 0], # Assuming single-step price prediction
'Predicted Price (' + ticker2 + ')': predictions_2[:, 0]},
index=pd.date_range(start=data1.index[-1] + pd.Timedelta(days=1),
periods=len(predictions_1)))
# Display the predicted prices
st.write("Predicted Prices for the Next Day:")
st.dataframe(prediction_df)
# # Display predictions
# st.dataframe(predictions_1)
# st.dataframe(predictions_2)
# st.write("Predictions for Next 3 Days:")
# st.write(f"{ticker1}: {predictions_1[-3:]}")
# st.write(f"{ticker2}: {predictions_2[-3:]}")