From 723a7dfc9feafd51047b8c8ba815f75cc29307ec Mon Sep 17 00:00:00 2001 From: "Bobby (aider)" Date: Wed, 12 Feb 2025 17:02:40 -0800 Subject: [PATCH] refactor: Move technical scanner functionality to separate module --- src/pages/screener/technical_scanner_page.py | 114 +++++++++++++++++++ src/streamlit_app.py | 111 +----------------- 2 files changed, 115 insertions(+), 110 deletions(-) create mode 100644 src/pages/screener/technical_scanner_page.py diff --git a/src/pages/screener/technical_scanner_page.py b/src/pages/screener/technical_scanner_page.py new file mode 100644 index 0000000..28a7c3a --- /dev/null +++ b/src/pages/screener/technical_scanner_page.py @@ -0,0 +1,114 @@ +import streamlit as st +from screener.scanner_controller import run_technical_scanner +import pandas as pd + +def technical_scanner_page(): + st.header("Technical Scanner") + + # Create tabs for scanner and reports + scanner_tab, reports_tab = st.tabs(["Run Scanner", "View Reports"]) + + with scanner_tab: + scanner_type = st.selectbox( + "Select Scanner", + ["SunnyBands", "ATR-EMA", "ATR-EMA v2"], + key="tech_scanner_type" + ) + + # Add interval selection + interval = st.selectbox( + "Select Time Interval", + ["Daily", "5 minute", "15 minute", "30 minute", "1 hour"], + key="interval_select" + ) + + # Convert interval to format expected by scanner + interval_map = { + "Daily": "1d", + "5 minute": "5m", + "15 minute": "15m", + "30 minute": "30m", + "1 hour": "1h" + } + selected_interval = interval_map[interval] + + # Date range selection + date_col1, date_col2 = st.columns(2) + with date_col1: + start_date = st.date_input("Start Date") + with date_col2: + end_date = st.date_input("End Date") + + col1, col2 = st.columns(2) + with col1: + min_price = st.number_input("Minimum Price", value=5.0, step=0.1) + max_price = st.number_input("Maximum Price", value=100.0, step=0.1) + + with col2: + min_volume = st.number_input("Minimum Volume", value=500000, step=100000) + portfolio_size = st.number_input("Portfolio Size", value=100000.0, step=1000.0) + + if st.button("Run Scanner"): + with st.spinner("Running scanner..."): + try: + signals = run_technical_scanner( + scanner_choice=scanner_type.lower().replace(" ", "_"), + start_date=start_date.strftime("%Y-%m-%d"), + end_date=end_date.strftime("%Y-%m-%d"), + min_price=min_price, + max_price=max_price, + min_volume=min_volume, + portfolio_size=portfolio_size, + interval=selected_interval + ) + if signals: + st.success(f"Found {len(signals)} signals") + for signal in signals: + with st.expander(f"{signal['ticker']} - ${signal['entry_price']:.2f}"): + col1, col2 = st.columns(2) + with col1: + st.metric("Entry Price", f"${signal['entry_price']:.2f}") + st.metric("Target", f"${signal['target_price']:.2f}") + st.metric("Stop Loss", f"${signal['stop_loss']:.2f}") + with col2: + st.metric("Shares", signal['shares']) + st.metric("Position Size", f"${signal['position_size']:.2f}") + st.metric("Risk Amount", f"${abs(signal['risk_amount']):.2f}") + else: + st.info("No signals found") + except Exception as e: + st.error(f"Error running scanner: {str(e)}") + + with reports_tab: + st.subheader("Scanner Reports") + + reports = load_scanner_reports() + if reports: + # Create a selectbox to choose the report + selected_report = st.selectbox( + "Select Report", + options=reports, + format_func=lambda x: f"{x['name']} ({x['created'].strftime('%Y-%m-%d %H:%M')})", + key="tech_scanner_report" + ) + + if selected_report: + try: + # Load and display the CSV + df = pd.read_csv(selected_report['path']) + + # Add download button + st.download_button( + label="Download Report", + data=df.to_csv(index=False), + file_name=selected_report['name'], + mime='text/csv' + ) + + # Display the dataframe + st.dataframe(df) + + except Exception as e: + st.error(f"Error loading report: {str(e)}") + else: + st.info("No scanner reports found") diff --git a/src/streamlit_app.py b/src/streamlit_app.py index f78c1d5..e956b91 100644 --- a/src/streamlit_app.py +++ b/src/streamlit_app.py @@ -4,6 +4,7 @@ from datetime import datetime import pytz from db.db_connection import create_client from pages.journal.trading_journal_page import trading_journal_page, format_datetime +from pages.screener.technical_scanner_page import technical_scanner_page from trading.journal import ( create_trades_table, get_open_trades, get_trade_history, get_latest_portfolio_value, update_portfolio_value @@ -31,116 +32,6 @@ def init_session_state(): -def technical_scanner_page(): - st.header("Technical Scanner") - - # Create tabs for scanner and reports - scanner_tab, reports_tab = st.tabs(["Run Scanner", "View Reports"]) - - with scanner_tab: - scanner_type = st.selectbox( - "Select Scanner", - ["SunnyBands", "ATR-EMA", "ATR-EMA v2"], - key="tech_scanner_type" - ) - - # Add interval selection - interval = st.selectbox( - "Select Time Interval", - ["Daily", "5 minute", "15 minute", "30 minute", "1 hour"], - key="interval_select" - ) - - # Convert interval to format expected by scanner - interval_map = { - "Daily": "1d", - "5 minute": "5m", - "15 minute": "15m", - "30 minute": "30m", - "1 hour": "1h" - } - selected_interval = interval_map[interval] - - # Date range selection - date_col1, date_col2 = st.columns(2) - with date_col1: - start_date = st.date_input("Start Date") - with date_col2: - end_date = st.date_input("End Date") - - col1, col2 = st.columns(2) - with col1: - min_price = st.number_input("Minimum Price", value=5.0, step=0.1) - max_price = st.number_input("Maximum Price", value=100.0, step=0.1) - - with col2: - min_volume = st.number_input("Minimum Volume", value=500000, step=100000) - portfolio_size = st.number_input("Portfolio Size", value=100000.0, step=1000.0) - - if st.button("Run Scanner"): - with st.spinner("Running scanner..."): - try: - signals = run_technical_scanner( - scanner_choice=scanner_type.lower().replace(" ", "_"), - start_date=start_date.strftime("%Y-%m-%d"), - end_date=end_date.strftime("%Y-%m-%d"), - min_price=min_price, - max_price=max_price, - min_volume=min_volume, - portfolio_size=portfolio_size, - interval=selected_interval - ) - if signals: - st.success(f"Found {len(signals)} signals") - for signal in signals: - with st.expander(f"{signal['ticker']} - ${signal['entry_price']:.2f}"): - col1, col2 = st.columns(2) - with col1: - st.metric("Entry Price", f"${signal['entry_price']:.2f}") - st.metric("Target", f"${signal['target_price']:.2f}") - st.metric("Stop Loss", f"${signal['stop_loss']:.2f}") - with col2: - st.metric("Shares", signal['shares']) - st.metric("Position Size", f"${signal['position_size']:.2f}") - st.metric("Risk Amount", f"${abs(signal['risk_amount']):.2f}") - else: - st.info("No signals found") - except Exception as e: - st.error(f"Error running scanner: {str(e)}") - - with reports_tab: - st.subheader("Scanner Reports") - - reports = load_scanner_reports() - if reports: - # Create a selectbox to choose the report - selected_report = st.selectbox( - "Select Report", - options=reports, - format_func=lambda x: f"{x['name']} ({x['created'].strftime('%Y-%m-%d %H:%M')})", - key="tech_scanner_report" - ) - - if selected_report: - try: - # Load and display the CSV - df = pd.read_csv(selected_report['path']) - - # Add download button - st.download_button( - label="Download Report", - data=df.to_csv(index=False), - file_name=selected_report['name'], - mime='text/csv' - ) - - # Display the dataframe - st.dataframe(df) - - except Exception as e: - st.error(f"Error loading report: {str(e)}") - else: - st.info("No scanner reports found") def trading_system_page():