import streamlit as st import plotly.graph_objects as go from datetime import datetime, timedelta import pandas as pd import numpy as np from utils.patterns import identify_patterns, calculate_technical_indicators from utils.predictions import predict_movement from utils.trading import fetch_market_data, is_market_open # Page configuration st.set_page_config( page_title="Trading Pattern Analysis", page_icon="📈", layout="wide" ) # Load custom CSS with open('styles/custom.css') as f: st.markdown(f'', unsafe_allow_html=True) # Pattern descriptions from the uploaded file PATTERN_DESCRIPTIONS = { 'HAMMER': 'Small body near the top with long lower wick, indicating buying pressure overcoming selling pressure.', 'INVERTED_HAMMER': 'Small body with long upper wick after downtrend, indicating resistance but potential upward movement.', 'PIERCING_LINE': 'Two-candlestick pattern where second closes above midpoint of first, signaling bullish shift.', 'BULLISH_ENGULFING': 'Small bearish candle followed by larger bullish candle that engulfs previous one.', 'MORNING_STAR': 'Three-candlestick pattern with bearish, small-bodied, and bullish candle indicating reversal.', 'THREE_WHITE_SOLDIERS': 'Three consecutive long bullish candles with small/no wicks, showing strong buying pressure.', 'BULLISH_HARAMI': 'Small bullish candle within body of preceding large bearish candle.', 'HANGING_MAN': 'Small body at top with long lower wick, signaling potential reversal.', 'DARK_CLOUD_COVER': 'Two-candlestick pattern with bearish closing below midpoint of previous bullish.', 'BEARISH_ENGULFING': 'Small bullish candle followed by larger bearish candle that engulfs it.', 'EVENING_STAR': 'Three-candlestick pattern with bullish, small-bodied, and bearish candle.', 'THREE_BLACK_CROWS': 'Three consecutive bearish candles showing strong selling.', 'SHOOTING_STAR': 'Small body with long upper wick, signaling resistance.', 'DOJI': 'Small body with wicks, showing market indecision.', 'DRAGONFLY_DOJI': 'Doji with long lower wick, showing buying pressure at bottom.', 'GRAVESTONE_DOJI': 'Doji with long upper wick, showing selling pressure at top.' } # Sidebar st.sidebar.title("Trading Controls") # Market Status Indicator market_open = is_market_open() status_color = "🟢" if market_open else "🔴" market_status = "Market Open" if market_open else "Market Closed" st.sidebar.write(f"{status_color} {market_status}") symbol = st.sidebar.text_input("Symbol", value="AAPL", help="Enter a valid stock symbol (e.g., AAPL, MSFT)") timeframe = st.sidebar.selectbox( "Timeframe", ["30m", "1h", "2h", "4h"], index=0, help="Select analysis timeframe (each candle represents 15 minutes)" ) # Add auto-refresh option auto_refresh = st.sidebar.checkbox("Auto-refresh data", value=True) if auto_refresh: st.sidebar.write("Updates every minute") st.rerun() # Use st.rerun() instead of experimental_rerun() # Main content st.title("Trading Pattern Analysis") try: # Fetch and process data with st.spinner('Fetching market data...'): df = fetch_market_data(symbol, period='1d', interval='15m') if len(df) >= 2: df = calculate_technical_indicators(df) patterns = identify_patterns(df) # Create candlestick chart fig = go.Figure(data=[go.Candlestick( x=df.index, open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'] )]) # Update layout for dark theme fig.update_layout( template="plotly_dark", plot_bgcolor="#252525", paper_bgcolor="#252525", xaxis_rangeslider_visible=False, height=600, title=f"{symbol} - Live Market Data ({timeframe} timeframe)" ) # Display chart st.plotly_chart(fig, use_container_width=True) # Pattern Analysis col1, col2 = st.columns(2) with col1: st.subheader("Pattern Analysis") if not patterns.empty and len(patterns) > 0: latest_patterns = patterns.iloc[-1] detected_patterns = latest_patterns[latest_patterns == 1].index.tolist() if detected_patterns: st.write("Detected Patterns:") for pattern in detected_patterns: st.markdown(f"""
{PATTERN_DESCRIPTIONS.get(pattern, '')}
Confidence: {confidence:.2%}
(Next 15-minute prediction)
{last_rsi:.2f}
({delta:+.2f})
{last_macd:.2f}
({delta:+.2f})
{last_sma:.2f}
({delta:+.2f})