feat: Add CANSLIM screener interface to Streamlit app
This commit is contained in:
parent
3bd73572af
commit
28f0eee4ec
@ -6,13 +6,16 @@ from screener.l_canslim import check_industry_leadership
|
||||
from screener.i_canslim import check_institutional_sponsorship
|
||||
from screener.csv_appender import append_scores_to_csv
|
||||
|
||||
def run_canslim_screener():
|
||||
def run_canslim_screener(start_date=None, end_date=None, selected_screeners=None):
|
||||
"""Run the CANSLIM screener"""
|
||||
user_start_date = input("Enter start date (YYYY-MM-DD): ")
|
||||
user_end_date = input("Enter end date (YYYY-MM-DD): ")
|
||||
if start_date is None or end_date is None:
|
||||
start_date = input("Enter start date (YYYY-MM-DD): ")
|
||||
end_date = input("Enter end date (YYYY-MM-DD): ")
|
||||
|
||||
start_date, end_date = validate_date_range(user_start_date, user_end_date, required_quarters=4)
|
||||
selected_screeners = get_user_screener_selection()
|
||||
if selected_screeners is None:
|
||||
selected_screeners = get_user_screener_selection()
|
||||
|
||||
start_date, end_date = validate_date_range(start_date, end_date, required_quarters=4)
|
||||
symbol_list = get_stocks_in_time_range(start_date, end_date)
|
||||
|
||||
if not symbol_list:
|
||||
|
||||
@ -367,6 +367,115 @@ def technical_scanner_page():
|
||||
else:
|
||||
st.info("No scanner reports found")
|
||||
|
||||
def canslim_screener_page():
|
||||
st.header("CANSLIM Screener")
|
||||
|
||||
# Create tabs for scanner and reports
|
||||
scanner_tab, reports_tab = st.tabs(["Run Scanner", "View Reports"])
|
||||
|
||||
with scanner_tab:
|
||||
# Date range selection
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
start_date = st.date_input("Start Date")
|
||||
with col2:
|
||||
end_date = st.date_input("End Date")
|
||||
|
||||
# CANSLIM criteria selection
|
||||
st.subheader("Select Screening Criteria")
|
||||
|
||||
c_criteria = st.expander("Current Quarterly Earnings (C)")
|
||||
with c_criteria:
|
||||
eps_threshold = st.slider("EPS Growth Threshold (%)", 0, 100, 25)
|
||||
sales_threshold = st.slider("Sales Growth Threshold (%)", 0, 100, 25)
|
||||
roe_threshold = st.slider("ROE Threshold (%)", 0, 50, 17)
|
||||
|
||||
a_criteria = st.expander("Annual Earnings Growth (A)")
|
||||
with a_criteria:
|
||||
annual_eps_threshold = st.slider("Annual EPS Growth Threshold (%)", 0, 100, 25)
|
||||
|
||||
l_criteria = st.expander("Industry Leadership (L)")
|
||||
with l_criteria:
|
||||
use_l = st.checkbox("Check Industry Leadership", value=True)
|
||||
l_threshold = st.slider("Industry Leadership Score Threshold", 0.0, 1.0, 0.7)
|
||||
|
||||
i_criteria = st.expander("Institutional Sponsorship (I)")
|
||||
with i_criteria:
|
||||
use_i = st.checkbox("Check Institutional Sponsorship", value=True)
|
||||
i_threshold = st.slider("Institutional Sponsorship Score Threshold", 0.0, 1.0, 0.7)
|
||||
|
||||
if st.button("Run CANSLIM Screener"):
|
||||
with st.spinner("Running CANSLIM screener..."):
|
||||
try:
|
||||
# Prepare selected screeners dictionary
|
||||
selected_screeners = {
|
||||
"C": {
|
||||
"EPS_Score": eps_threshold / 100,
|
||||
"Sales_Score": sales_threshold / 100,
|
||||
"ROE_Score": roe_threshold / 100
|
||||
},
|
||||
"A": {
|
||||
"Annual_EPS_Score": annual_eps_threshold / 100
|
||||
}
|
||||
}
|
||||
|
||||
if use_l:
|
||||
selected_screeners["L"] = {"L_Score": l_threshold}
|
||||
if use_i:
|
||||
selected_screeners["I"] = {"I_Score": i_threshold}
|
||||
|
||||
# Convert dates to strings for the screener
|
||||
start_str = start_date.strftime("%Y-%m-%d")
|
||||
end_str = end_date.strftime("%Y-%m-%d")
|
||||
|
||||
# Run the screener
|
||||
st.session_state.screener_params = {
|
||||
"start_date": start_str,
|
||||
"end_date": end_str,
|
||||
"selected_screeners": selected_screeners
|
||||
}
|
||||
|
||||
# Modify run_canslim_screener to accept parameters
|
||||
run_canslim_screener()
|
||||
st.success("Screening complete! Check the Reports tab for results.")
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error running CANSLIM screener: {str(e)}")
|
||||
|
||||
with reports_tab:
|
||||
st.subheader("CANSLIM Reports")
|
||||
|
||||
# Use the same report loading function but look in a CANSLIM-specific directory
|
||||
reports = load_scanner_reports() # You might want to modify this to look in a CANSLIM directory
|
||||
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')})"
|
||||
)
|
||||
|
||||
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 CANSLIM reports found")
|
||||
|
||||
def main():
|
||||
st.set_page_config(page_title="Trading System", layout="wide")
|
||||
init_session_state()
|
||||
@ -387,8 +496,7 @@ def main():
|
||||
elif st.session_state.page == "Technical Scanner":
|
||||
technical_scanner_page()
|
||||
elif st.session_state.page == "CANSLIM Screener":
|
||||
st.header("CANSLIM Screener")
|
||||
# Add CANSLIM screener implementation
|
||||
canslim_screener_page()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user