refactor: Move technical scanner functionality to separate module
This commit is contained in:
parent
3bb0ede559
commit
723a7dfc9f
114
src/pages/screener/technical_scanner_page.py
Normal file
114
src/pages/screener/technical_scanner_page.py
Normal file
@ -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")
|
||||||
@ -4,6 +4,7 @@ from datetime import datetime
|
|||||||
import pytz
|
import pytz
|
||||||
from db.db_connection import create_client
|
from db.db_connection import create_client
|
||||||
from pages.journal.trading_journal_page import trading_journal_page, format_datetime
|
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 (
|
from trading.journal import (
|
||||||
create_trades_table, get_open_trades, get_trade_history,
|
create_trades_table, get_open_trades, get_trade_history,
|
||||||
get_latest_portfolio_value, update_portfolio_value
|
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():
|
def trading_system_page():
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user