From b4b270954bb87b48ec8fbd7549e3dc39ca5d8629 Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 26 Aug 2025 17:02:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3Kronos=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E9=A2=84=E6=B5=8B=E8=BF=9E=E7=BB=AD=E6=80=A7=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C=E9=80=9A=E8=BF=87=E4=BB=B7=E6=A0=BC=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E4=BF=9D=E6=8C=81=E6=95=B0=E6=8D=AE=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webui/app.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/webui/app.py b/webui/app.py index 38de059..b478cd8 100644 --- a/webui/app.py +++ b/webui/app.py @@ -122,6 +122,31 @@ def load_data_file(file_path): except Exception as e: return None, f"加载文件失败: {str(e)}" +def convert_price_to_returns(df, price_cols=['open', 'high', 'low', 'close']): + """将绝对价格转换为相对变化率,解决Kronos模型的连续性问题""" + returns_df = df.copy() + + # 计算相对变化率 (pct_change) + for col in price_cols: + if col in returns_df.columns: + returns_df[col] = returns_df[col].pct_change() + + # 第一行会是NaN,用0填充 + returns_df = returns_df.fillna(0) + + return returns_df + +def convert_returns_to_price(returns_df, initial_prices, price_cols=['open', 'high', 'low', 'close']): + """将相对变化率转换回绝对价格""" + price_df = returns_df.copy() + + for col in price_cols: + if col in price_df.columns: + # 从初始价格开始,逐步计算绝对价格 + price_df[col] = (1 + returns_df[col]) * initial_prices[col] + + return price_df + def save_prediction_results(file_path, prediction_type, prediction_results, actual_data, input_data, prediction_params): """保存预测结果到文件""" try: @@ -476,8 +501,21 @@ def predict(): if isinstance(y_timestamp, pd.DatetimeIndex): y_timestamp = pd.Series(y_timestamp, name='timestamps') - pred_df = predictor.predict( - df=x_df, + # 解决Kronos模型连续性问题:将绝对价格转换为相对变化率 + original_x_df = x_df.copy() + initial_prices = { + 'open': x_df['open'].iloc[0], + 'high': x_df['high'].iloc[0], + 'low': x_df['low'].iloc[0], + 'close': x_df['close'].iloc[0] + } + + # 转换为相对变化率 + x_df_returns = convert_price_to_returns(x_df, ['open', 'high', 'low', 'close']) + + # 使用转换后的数据进行预测 + pred_df_returns = predictor.predict( + df=x_df_returns, x_timestamp=x_timestamp, y_timestamp=y_timestamp, pred_len=pred_len, @@ -486,6 +524,15 @@ def predict(): sample_count=sample_count ) + # 将预测结果转换回绝对价格 + pred_df = convert_returns_to_price(pred_df_returns, initial_prices, ['open', 'high', 'low', 'close']) + + # 保持volume列不变(如果存在) + if 'volume' in pred_df.columns: + pred_df['volume'] = pred_df_returns['volume'] + if 'amount' in pred_df.columns: + pred_df['amount'] = pred_df_returns['amount'] + except Exception as e: return jsonify({'error': f'Kronos模型预测失败: {str(e)}'}), 500 else: