refactor: Move backtesting form from sidebar to main page layout

This commit is contained in:
Bobby (aider) 2025-02-13 23:09:25 -08:00
parent b41046105d
commit f90794a11c

View File

@ -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()
with left_col:
st.subheader("Backtest Settings")
# 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")
# Ticker selection
ticker = st.text_input("Enter Ticker Symbol", value="AAPL").upper()
# Indicator selection
available_indicators = get_available_indicators()
selected_indicators = st.sidebar.multiselect(
"Select Technical Indicators",
options=list(available_indicators.keys())
)
# 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")
# Parameter input/optimization section
optimize = st.sidebar.checkbox("Optimize Parameters")
# Indicator selection
available_indicators = get_available_indicators()
selected_indicators = st.multiselect(
"Select Technical Indicators",
options=list(available_indicators.keys())
)
indicator_settings = {}
for ind_name in selected_indicators:
st.sidebar.subheader(f"{ind_name} Settings")
ind_config = available_indicators[ind_name]
# Parameter input/optimization section
optimize = st.checkbox("Optimize Parameters")
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))
indicator_settings = {}
for ind_name in selected_indicators:
st.subheader(f"{ind_name} Settings")
ind_config = available_indicators[ind_name]
indicator_settings[ind_name] = {
'type': ind_name,
'params': params
}
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))
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')
indicator_settings[ind_name] = {
'type': ind_name,
'params': params
}
if df.empty:
st.error("No data available for the selected period")
return
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')
try:
df = prepare_data_for_backtest(df)
if df.empty:
st.error("No data available for the selected period")
return
if optimize:
results = run_optimization(df, indicator_settings)
display_optimization_results(results)
else:
results = run_single_backtest(df, indicator_settings)
display_backtest_results(results)
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"""