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():
|
def backtesting_page():
|
||||||
st.title("Strategy Backtesting")
|
st.title("Strategy Backtesting")
|
||||||
|
|
||||||
# Sidebar controls
|
# Create two columns for the main layout
|
||||||
st.sidebar.subheader("Backtest Settings")
|
left_col, right_col = st.columns([2, 3])
|
||||||
|
|
||||||
# Ticker selection
|
with left_col:
|
||||||
ticker = st.sidebar.text_input("Enter Ticker Symbol", value="AAPL").upper()
|
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")
|
|
||||||
|
|
||||||
# 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]
|
|
||||||
|
|
||||||
if optimize:
|
# Ticker selection
|
||||||
params = {}
|
ticker = st.text_input("Enter Ticker Symbol", value="AAPL").upper()
|
||||||
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[ind_name] = {
|
# Date range selection
|
||||||
'type': ind_name,
|
col1, col2 = st.columns(2)
|
||||||
'params': params
|
with col1:
|
||||||
}
|
start_date = st.date_input("Start Date",
|
||||||
|
value=datetime.now() - timedelta(days=365))
|
||||||
if st.sidebar.button("Run Backtest"):
|
with col2:
|
||||||
with st.spinner('Running backtest...'):
|
end_date = st.date_input("End Date")
|
||||||
# Fetch data
|
|
||||||
# Convert date to datetime
|
# Indicator selection
|
||||||
start_datetime = datetime.combine(start_date, datetime.min.time())
|
available_indicators = get_available_indicators()
|
||||||
end_datetime = datetime.combine(end_date, datetime.min.time())
|
selected_indicators = st.multiselect(
|
||||||
df = get_stock_data(ticker, start_datetime, end_datetime, 'daily')
|
"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:
|
if optimize:
|
||||||
st.error("No data available for the selected period")
|
params = {}
|
||||||
return
|
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:
|
indicator_settings[ind_name] = {
|
||||||
df = prepare_data_for_backtest(df)
|
'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:
|
if df.empty:
|
||||||
results = run_optimization(df, indicator_settings)
|
st.error("No data available for the selected period")
|
||||||
display_optimization_results(results)
|
return
|
||||||
else:
|
|
||||||
results = run_single_backtest(df, indicator_settings)
|
try:
|
||||||
display_backtest_results(results)
|
df = prepare_data_for_backtest(df)
|
||||||
|
|
||||||
except Exception as e:
|
if optimize:
|
||||||
st.error(f"Error during backtest: {str(e)}")
|
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:
|
def run_optimization(df: pd.DataFrame, indicator_settings: Dict) -> List:
|
||||||
"""Run optimization with different parameter combinations"""
|
"""Run optimization with different parameter combinations"""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user