add tuning lab view with navigation hints between tuning and backtest
This commit is contained in:
parent
c9c27cc5af
commit
2062a11181
12
app/ui/navigation.py
Normal file
12
app/ui/navigation.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
"""Helpers for navigating between top-level Streamlit menus."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import streamlit as st
|
||||||
|
|
||||||
|
TOP_NAV_STATE_KEY = "top_nav"
|
||||||
|
|
||||||
|
|
||||||
|
def navigate_top_menu(label: str) -> None:
|
||||||
|
"""Set the active top navigation label and rerun the app."""
|
||||||
|
st.session_state[TOP_NAV_STATE_KEY] = label
|
||||||
|
st.experimental_rerun()
|
||||||
@ -8,6 +8,7 @@ import streamlit as st
|
|||||||
|
|
||||||
from app.utils.db import db_session
|
from app.utils.db import db_session
|
||||||
from app.utils.logging import get_logger
|
from app.utils.logging import get_logger
|
||||||
|
from app.ui.navigation import navigate_top_menu
|
||||||
|
|
||||||
LOGGER = get_logger(__name__)
|
LOGGER = get_logger(__name__)
|
||||||
LOG_EXTRA = {"stage": "ui"}
|
LOG_EXTRA = {"stage": "ui"}
|
||||||
@ -63,3 +64,16 @@ def default_backtest_range(window_days: int = 60) -> tuple[date, date]:
|
|||||||
if start > latest:
|
if start > latest:
|
||||||
start = latest
|
start = latest
|
||||||
return start, latest
|
return start, latest
|
||||||
|
|
||||||
|
|
||||||
|
def render_tuning_backtest_hints(current_label: Optional[str] = None) -> None:
|
||||||
|
"""Render navigation shortcuts that keep tuning and backtest flows connected."""
|
||||||
|
key_tag = (current_label or "global").replace("/", "_")
|
||||||
|
hint_box = st.container()
|
||||||
|
with hint_box:
|
||||||
|
col_go_bt, col_go_tune, col_text = st.columns([1, 1, 3])
|
||||||
|
if col_go_bt.button("回测与复盘", key=f"hint_nav_backtest_{key_tag}"):
|
||||||
|
navigate_top_menu("回测与复盘")
|
||||||
|
if col_go_tune.button("实验调参", key=f"hint_nav_tuning_{key_tag}"):
|
||||||
|
navigate_top_menu("实验调参")
|
||||||
|
col_text.caption("提示:调参完成后记得回测验证,回测发现问题也可随时跳回调参实验。")
|
||||||
|
|||||||
@ -16,7 +16,7 @@ from app.ingest.checker import run_boot_check
|
|||||||
from app.ingest.rss import ingest_configured_rss
|
from app.ingest.rss import ingest_configured_rss
|
||||||
from app.ui.portfolio_config import render_portfolio_config
|
from app.ui.portfolio_config import render_portfolio_config
|
||||||
from app.ui.progress_state import render_factor_progress
|
from app.ui.progress_state import render_factor_progress
|
||||||
from app.ui.shared import LOGGER, LOG_EXTRA
|
from app.ui.shared import LOGGER, LOG_EXTRA, render_tuning_backtest_hints
|
||||||
from app.ui.views import (
|
from app.ui.views import (
|
||||||
render_backtest_review,
|
render_backtest_review,
|
||||||
render_config_overview,
|
render_config_overview,
|
||||||
@ -30,9 +30,11 @@ from app.ui.views import (
|
|||||||
render_tests,
|
render_tests,
|
||||||
render_today_plan,
|
render_today_plan,
|
||||||
render_factor_calculation,
|
render_factor_calculation,
|
||||||
|
render_tuning_lab,
|
||||||
)
|
)
|
||||||
from app.utils.config import get_config
|
from app.utils.config import get_config
|
||||||
|
|
||||||
|
from app.ui.navigation import TOP_NAV_STATE_KEY
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
LOGGER.info("初始化 Streamlit UI", extra=LOG_EXTRA)
|
LOGGER.info("初始化 Streamlit UI", extra=LOG_EXTRA)
|
||||||
@ -74,15 +76,25 @@ def main() -> None:
|
|||||||
render_global_dashboard()
|
render_global_dashboard()
|
||||||
|
|
||||||
# --- 顶部导航(第三方组件 streamlit-option-menu) ---
|
# --- 顶部导航(第三方组件 streamlit-option-menu) ---
|
||||||
top_labels = ["今日计划", "投资池/仓位", "回测与复盘", "行情可视化", "日志钻取", "数据与设置", "自检测试"]
|
top_labels = ["今日计划", "投资池/仓位", "回测与复盘", "实验调参", "行情可视化", "日志钻取", "数据与设置", "自检测试"]
|
||||||
|
if TOP_NAV_STATE_KEY not in st.session_state:
|
||||||
|
st.session_state[TOP_NAV_STATE_KEY] = top_labels[0]
|
||||||
|
try:
|
||||||
|
default_index = top_labels.index(st.session_state[TOP_NAV_STATE_KEY])
|
||||||
|
except ValueError:
|
||||||
|
default_index = 0
|
||||||
selected_top = option_menu(
|
selected_top = option_menu(
|
||||||
menu_title=None,
|
menu_title=None,
|
||||||
options=top_labels,
|
options=top_labels,
|
||||||
icons=["calendar", "briefcase", "bar-chart", "activity", "file-text", "gear", "bug"],
|
icons=["calendar", "briefcase", "bar-chart", "cpu", "activity", "file-text", "gear", "bug"],
|
||||||
orientation="horizontal",
|
orientation="horizontal",
|
||||||
|
default_index=default_index,
|
||||||
)
|
)
|
||||||
|
st.session_state[TOP_NAV_STATE_KEY] = selected_top
|
||||||
LOGGER.debug("Top menu selected: %s", selected_top, extra=LOG_EXTRA)
|
LOGGER.debug("Top menu selected: %s", selected_top, extra=LOG_EXTRA)
|
||||||
|
|
||||||
|
render_tuning_backtest_hints(selected_top)
|
||||||
|
|
||||||
# --- 仅渲染当前选中页(懒加载) ---
|
# --- 仅渲染当前选中页(懒加载) ---
|
||||||
if selected_top == "今日计划":
|
if selected_top == "今日计划":
|
||||||
render_today_plan()
|
render_today_plan()
|
||||||
@ -107,6 +119,9 @@ def main() -> None:
|
|||||||
else:
|
else:
|
||||||
render_factor_calculation()
|
render_factor_calculation()
|
||||||
|
|
||||||
|
elif selected_top == "实验调参":
|
||||||
|
render_tuning_lab()
|
||||||
|
|
||||||
elif selected_top == "行情可视化":
|
elif selected_top == "行情可视化":
|
||||||
render_market_visualization()
|
render_market_visualization()
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ from .tests import render_tests
|
|||||||
from .dashboard import render_global_dashboard, update_dashboard_sidebar
|
from .dashboard import render_global_dashboard, update_dashboard_sidebar
|
||||||
from .stock_eval import render_stock_evaluation
|
from .stock_eval import render_stock_evaluation
|
||||||
from .factor_calculation import render_factor_calculation
|
from .factor_calculation import render_factor_calculation
|
||||||
|
from .tuning import render_tuning_lab
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"render_today_plan",
|
"render_today_plan",
|
||||||
@ -25,4 +26,5 @@ __all__ = [
|
|||||||
"update_dashboard_sidebar",
|
"update_dashboard_sidebar",
|
||||||
"render_stock_evaluation",
|
"render_stock_evaluation",
|
||||||
"render_factor_calculation",
|
"render_factor_calculation",
|
||||||
|
"render_tuning_lab",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -12,21 +12,15 @@ import numpy as np
|
|||||||
|
|
||||||
from app.agents.base import AgentContext
|
from app.agents.base import AgentContext
|
||||||
from app.agents.game import Decision
|
from app.agents.game import Decision
|
||||||
from app.agents.registry import default_agents
|
|
||||||
from app.agents.protocols import GameStructure
|
from app.agents.protocols import GameStructure
|
||||||
from app.backtest.decision_env import DecisionEnv, ParameterSpec
|
|
||||||
from app.backtest.optimizer import BanditConfig, EpsilonGreedyBandit
|
|
||||||
from app.rl import TORCH_AVAILABLE, DecisionEnvAdapter, PPOConfig, train_ppo
|
|
||||||
from app.backtest.engine import BacktestEngine, PortfolioState, BtConfig, run_backtest
|
from app.backtest.engine import BacktestEngine, PortfolioState, BtConfig, run_backtest
|
||||||
from app.ingest.checker import run_boot_check
|
from app.ingest.checker import run_boot_check
|
||||||
from app.ingest.tushare import run_ingestion
|
from app.ingest.tushare import run_ingestion
|
||||||
from app.llm.client import run_llm
|
from app.llm.client import run_llm
|
||||||
from app.llm.metrics import reset as reset_llm_metrics
|
from app.llm.metrics import reset as reset_llm_metrics
|
||||||
from app.llm.metrics import snapshot as snapshot_llm_metrics
|
from app.llm.metrics import snapshot as snapshot_llm_metrics
|
||||||
from app.llm.templates import TemplateRegistry
|
|
||||||
from app.utils import alerts
|
from app.utils import alerts
|
||||||
from app.utils.config import get_config, save_config
|
from app.utils.config import get_config, save_config
|
||||||
from app.utils.tuning import log_tuning_result
|
|
||||||
from app.utils.portfolio import (
|
from app.utils.portfolio import (
|
||||||
get_candidate_pool,
|
get_candidate_pool,
|
||||||
get_portfolio_settings_snapshot,
|
get_portfolio_settings_snapshot,
|
||||||
@ -206,7 +200,7 @@ def render_backtest_review() -> None:
|
|||||||
extra=LOG_EXTRA,
|
extra=LOG_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
tab_backtest, tab_rl = st.tabs(["回测验证", "强化学习调参"])
|
tab_backtest, tab_tuning = st.tabs(["回测复盘", "实验调参"])
|
||||||
|
|
||||||
with tab_backtest:
|
with tab_backtest:
|
||||||
st.markdown("#### 回测执行")
|
st.markdown("#### 回测执行")
|
||||||
|
|||||||
1082
app/ui/views/tuning.py
Normal file
1082
app/ui/views/tuning.py
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user