refactor: Move backtesting form from sidebar to main page layout
This commit is contained in:
parent
b41046105d
commit
f90794a11c
@ -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"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user