From f90794a11c53aaacf347f83ae269e7748dea55e2 Mon Sep 17 00:00:00 2001 From: "Bobby (aider)" Date: Thu, 13 Feb 2025 23:09:25 -0800 Subject: [PATCH] refactor: Move backtesting form from sidebar to main page layout --- src/pages/backtesting/backtesting_page.py | 151 +++++++++++----------- 1 file changed, 78 insertions(+), 73 deletions(-) diff --git a/src/pages/backtesting/backtesting_page.py b/src/pages/backtesting/backtesting_page.py index 5e9d6e1..caad559 100644 --- a/src/pages/backtesting/backtesting_page.py +++ b/src/pages/backtesting/backtesting_page.py @@ -113,86 +113,91 @@ def prepare_data_for_backtest(df: pd.DataFrame) -> pd.DataFrame: def backtesting_page(): st.title("Strategy Backtesting") - # Sidebar controls - st.sidebar.subheader("Backtest Settings") + # Create two columns for the main layout + left_col, right_col = st.columns([2, 3]) - # Ticker selection - ticker = st.sidebar.text_input("Enter Ticker Symbol", value="AAPL").upper() - - # Date range selection - col1, col2 = st.sidebar.columns(2) - with col1: - start_date = st.date_input("Start Date", - value=datetime.now() - timedelta(days=365)) - with col2: - end_date = st.date_input("End Date") - - # Indicator selection - available_indicators = get_available_indicators() - selected_indicators = st.sidebar.multiselect( - "Select Technical Indicators", - options=list(available_indicators.keys()) - ) - - # Parameter input/optimization section - optimize = st.sidebar.checkbox("Optimize Parameters") - - indicator_settings = {} - for ind_name in selected_indicators: - st.sidebar.subheader(f"{ind_name} Settings") - ind_config = available_indicators[ind_name] + with left_col: + st.subheader("Backtest Settings") - if optimize: - params = {} - for param in ind_config['params']: - param_range = ind_config['ranges'][param] - col1, col2, col3 = st.sidebar.columns(3) - with col1: - min_val = st.number_input(f"{param} Min", - value=float(param_range[0])) - with col2: - max_val = st.number_input(f"{param} Max", - value=float(param_range[1])) - with col3: - step = st.number_input(f"{param} Step", - value=1.0 if param == 'std' else 1) - params[param] = {'min': min_val, 'max': max_val, 'step': step} - else: - params = {} - for param in ind_config['params']: - default_val = ind_config['defaults'][param] - params[param] = st.sidebar.number_input(f"{param}", - value=float(default_val)) + # Ticker selection + ticker = st.text_input("Enter Ticker Symbol", value="AAPL").upper() - indicator_settings[ind_name] = { - 'type': ind_name, - 'params': params - } - - if st.sidebar.button("Run Backtest"): - with st.spinner('Running backtest...'): - # Fetch data - # Convert date to datetime - start_datetime = datetime.combine(start_date, datetime.min.time()) - end_datetime = datetime.combine(end_date, datetime.min.time()) - df = get_stock_data(ticker, start_datetime, end_datetime, 'daily') + # Date range selection + col1, col2 = st.columns(2) + with col1: + start_date = st.date_input("Start Date", + value=datetime.now() - timedelta(days=365)) + with col2: + end_date = st.date_input("End Date") + + # Indicator selection + available_indicators = get_available_indicators() + selected_indicators = st.multiselect( + "Select Technical Indicators", + options=list(available_indicators.keys()) + ) + + # Parameter input/optimization section + optimize = st.checkbox("Optimize Parameters") + + indicator_settings = {} + for ind_name in selected_indicators: + st.subheader(f"{ind_name} Settings") + ind_config = available_indicators[ind_name] - if df.empty: - st.error("No data available for the selected period") - return + if optimize: + params = {} + for param in ind_config['params']: + param_range = ind_config['ranges'][param] + col1, col2, col3 = st.columns(3) + with col1: + min_val = st.number_input(f"{param} Min", + value=float(param_range[0])) + with col2: + max_val = st.number_input(f"{param} Max", + value=float(param_range[1])) + with col3: + step = st.number_input(f"{param} Step", + value=1.0 if param == 'std' else 1) + params[param] = {'min': min_val, 'max': max_val, 'step': step} + else: + params = {} + for param in ind_config['params']: + default_val = ind_config['defaults'][param] + params[param] = st.number_input(f"{param}", + value=float(default_val)) - try: - df = prepare_data_for_backtest(df) + indicator_settings[ind_name] = { + 'type': ind_name, + 'params': params + } + + if st.button("Run Backtest"): + with st.spinner('Running backtest...'): + # Fetch data + # Convert date to datetime + start_datetime = datetime.combine(start_date, datetime.min.time()) + end_datetime = datetime.combine(end_date, datetime.min.time()) + df = get_stock_data(ticker, start_datetime, end_datetime, 'daily') - if optimize: - results = run_optimization(df, indicator_settings) - display_optimization_results(results) - else: - results = run_single_backtest(df, indicator_settings) - display_backtest_results(results) + if df.empty: + st.error("No data available for the selected period") + return + + try: + df = prepare_data_for_backtest(df) - except Exception as e: - st.error(f"Error during backtest: {str(e)}") + if optimize: + results = run_optimization(df, indicator_settings) + with right_col: + display_optimization_results(results) + else: + results = run_single_backtest(df, indicator_settings) + with right_col: + display_backtest_results(results) + + except Exception as e: + st.error(f"Error during backtest: {str(e)}") def run_optimization(df: pd.DataFrame, indicator_settings: Dict) -> List: """Run optimization with different parameter combinations"""