claraleeee/hftpredict
0
1# app.py2import streamlit as st3from predict import predict_for, build_a_stock_minutes, build_us_minutes, trading_minutes_for_date4import matplotlib.pyplot as plt5import pandas as pd6 7st.set_page_config(page_title="📈 股票预测系统", layout="wide")8st.title("📈 股票价格预测系统")9 10market = st.radio("选择市场类型", ["A股 / ETF", "美股"])11code = st.text_input("输入股票代码", "sh601988" if market == "A股 / ETF" else "AAPL")12date = st.text_input("预测日期 (YYYY-MM-DD)", "2025-11-13")13open_price = st.number_input("开盘价", value=5.77 if market == "A股 / ETF" else 510.0)14run = st.button("运行预测")15 16if run:17 mkt_key = "a" if market == "A股 / ETF" else "us"18 outs = predict_for(mkt_key, code, date, open_price=open_price)19 20 # build prediction span bounds from predicted timelines only21 pred_mins = [pd.to_datetime(df["datetime"].min()) for df in outs]22 pred_maxs = [pd.to_datetime(df["datetime"].max()) for df in outs]23 pred_min = min(pred_mins)24 pred_max = max(pred_maxs)25 26 # fetch actual data but then restrict to prediction window27 if market == "A股 / ETF":28 df_actual = build_a_stock_minutes(code, days=3) # fetch a few days to ensure coverage29 else:30 df_actual = build_us_minutes(code, days=3)31 # filter actual to the pred window (so old 15:00 won't affect x axis)32 df_actual = df_actual[(pd.to_datetime(df_actual["datetime"]) >= pred_min) & 33 (pd.to_datetime(df_actual["datetime"]) <= pred_max)].reset_index(drop=True)34 35 # plotting36 fig, ax = plt.subplots(figsize=(12, 5))37 if not df_actual.empty:38 ax.plot(pd.to_datetime(df_actual["datetime"]), df_actual["close"], label="实际价格", color="gray", linewidth=1.5)39 40 ymin = None; ymax = None41 for df in outs:42 times = pd.to_datetime(df["datetime"])43 prices = pd.to_numeric(df["predicted_price"], errors="coerce")44 ax.plot(times, prices, label=df["model"], linewidth=2)45 if ymin is None or (prices.min() < ymin):46 ymin = float(prices.min())47 if ymax is None or (prices.max() > ymax):48 ymax = float(prices.max())49 50 # if actual present, include its range as well51 if not df_actual.empty:52 ymin = min(ymin if ymin is not None else float(df_actual["close"].min()), float(df_actual["close"].min()))53 ymax = max(ymax if ymax is not None else float(df_actual["close"].max()), float(df_actual["close"].max()))54 55 # set xlim to prediction window explicitly to avoid previous-day bleed56 ax.set_xlim(pred_min, pred_max)57 58 if ymin is not None and ymax is not None:59 margin = max((ymax - ymin) * 0.03, 0.01)60 ax.set_ylim(ymin - margin, ymax + margin)61 62 ax.legend(loc="upper left", bbox_to_anchor=(1.01, 1), borderaxespad=0)63 ax.set_title(f"{market} {code} 预测日期:{date}")64 ax.set_xlabel("时间")65 ax.set_ylabel("价格")66 st.pyplot(fig)67 