Humphreykowl commited on
Commit
3dd04f4
·
verified ·
1 Parent(s): 0661f5c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +384 -82
app.py CHANGED
@@ -2,6 +2,7 @@
2
  """
3
  港股智能分析平台 - Hugging Face Spaces版本
4
  集成数学原理的XPINNs训练与LLM推理系统
 
5
  """
6
 
7
  import os
@@ -64,7 +65,7 @@ class FiberBundleTheory:
64
  def __init__(self, base_dim=2, fiber_dim=16):
65
  self.base_dim = base_dim # VIX^2, RV
66
  self.fiber_dim = fiber_dim # 隐藏状态维度
67
- self.whitney_factor = 2 * fiber_dim # Whitney嵌入
68
 
69
  def project_to_base(self, high_dim_state):
70
  """投影到基空间"""
@@ -72,7 +73,7 @@ class FiberBundleTheory:
72
  high_dim_state = np.pad(high_dim_state, (0, self.fiber_dim - len(high_dim_state)))
73
 
74
  # 计算VIX^2代理
75
- vix_squared = np.sum(high_dim_state[:self.fiber_dim//2]**2) / (self.fiber_dim//2)
76
  # 计算实现波动率
77
  rv = np.std(high_dim_state[self.fiber_dim//2:])
78
 
@@ -83,6 +84,182 @@ class FiberBundleTheory:
83
  vix_squared, rv = base_point
84
  return vix_squared - rv
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  class EquivariantLayer(nn.Module):
87
  """SO(3)等变层"""
88
 
@@ -230,12 +407,17 @@ class CausalVAR:
230
  class MathematicalTrainer:
231
  """数学原理驱动的训练器"""
232
 
233
- def __init__(self):
234
- self.fiber_bundle = FiberBundleTheory()
235
- self.causal_var = CausalVAR()
 
236
  self.model = XPINNsGenerator()
237
  self.optimizer = Adam(self.model.parameters(), lr=0.001)
238
  self.scaler = StandardScaler()
 
 
 
 
239
 
240
  def prepare_data(self, df):
241
  """准备训练数据"""
@@ -324,6 +506,35 @@ class MathematicalTrainer:
324
  logger.info(f"Epoch {epoch}: Loss = {avg_loss:.6f}")
325
 
326
  return losses
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
 
328
  class LLMInterface:
329
  """LLM接口"""
@@ -340,7 +551,7 @@ class LLMInterface:
340
  "inputs": prompt,
341
  "parameters": {
342
  "max_new_tokens": max_length,
343
- "temperature": 0.7,
344
  "top_p": 0.9,
345
  "do_sample": True
346
  }
@@ -358,34 +569,77 @@ class LLMInterface:
358
  except Exception as e:
359
  return f"错误: {str(e)}"
360
 
361
- def analyze_trading(self, analysis_results, market_data):
362
- """分析交易策略"""
363
- prompt = f"""作为量化交易专家基于以下数学分析结果制日内交易策略:
364
-
365
- 数学分析结果:
366
- - 因果稳定性: {analysis_results.get('causal_stable', 'N/A')}
367
- - VRP值: {analysis_results.get('vrp', 'N/A')}
368
- - 李雅普诺夫稳定性: {analysis_results.get('lyapunov_stable', 'N/A')}
369
- - 纤维丛投影: {analysis_results.get('fiber_projection', 'N/A')}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
 
371
  市场数据摘要:
372
  {market_data}
373
 
374
- 提供
375
- 1. 具体的入场建议
376
- 2. 止损和止盈设置
377
- 3. 仓位管理建议
378
- 4. 风险提示
379
 
380
- 回答应简洁专业,直接给可执行的交易建议。"""
381
-
382
- return self.query(prompt)
 
383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
384
  class TradingPlatform:
385
  """主交易平台"""
386
 
387
- def __init__(self):
388
- self.trainer = MathematicalTrainer()
389
  self.llm = LLMInterface()
390
  self.current_data = None
391
  self.analysis_results = {}
@@ -473,7 +727,43 @@ class TradingPlatform:
473
  except Exception as e:
474
  return f"训练失败: {str(e)}", None
475
 
476
- def get_trading_strategy(self, user_question):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  """获取交易策略"""
478
  if not self.analysis_results:
479
  return "请先上传并分析数据"
@@ -484,14 +774,18 @@ class TradingPlatform:
484
  if self.current_data is not None:
485
  numeric_cols = self.current_data.select_dtypes(include=[np.number]).columns
486
  if len(numeric_cols) > 0:
487
- latest_data = self.current_data[numeric_cols].tail(5).describe()
488
  market_summary = latest_data.to_string()
489
 
490
  # 合并用户问题
491
  full_prompt = f"{user_question}\n\n当前分析结果:{json.dumps(self.analysis_results, indent=2)}\n\n市场数据:{market_summary}"
492
 
 
 
 
 
493
  # 获取LLM回复
494
- response = self.llm.analyze_trading(self.analysis_results, full_prompt)
495
 
496
  return response
497
 
@@ -504,14 +798,13 @@ def create_interface():
504
 
505
  with gr.Blocks(title="港股智能分析平台", theme=gr.themes.Soft()) as interface:
506
  gr.Markdown("""
507
- # 🚀 港股智能分析平台 - 数学原理驱动
508
-
509
- ### 核心特性
510
- - 📊 **纤维丛理论**:高维市场状态的几何投影
511
- - 🔄 **因果VAR模型**:动态因果关系发现
512
- - 🌀 **等变神经网络**:SO(3)群对称性约束
513
- - 🎯 **XPINNs生器**:物理约束的域分解
514
- - 🤖 **LLM策略生成**:基于数学分析的交易建议
515
  """)
516
 
517
  with gr.Tabs():
@@ -547,6 +840,23 @@ def create_interface():
547
  outputs=[data_summary, analysis_result, status_text]
548
  )
549
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  # 模型训练标签
551
  with gr.TabItem("🧮 XPINNs模型训练"):
552
  with gr.Row():
@@ -577,15 +887,13 @@ def create_interface():
577
  # 交易策略标签
578
  with gr.TabItem("💹 智能交易策略"):
579
  gr.Markdown("""
580
- ### 基于数学原理的交易策略生成
581
 
582
  系统将结合:
583
  - 纤维丛投影的市场状态
584
  - 因果VAR的动态关系
585
- - 李雅普诺夫稳定性分析
586
- - LLM智能推理
587
-
588
- 为您生成专业的日内交易策略。
589
  """)
590
 
591
  with gr.Row():
@@ -599,16 +907,18 @@ def create_interface():
599
 
600
  user_input = gr.Textbox(
601
  label="交易问题",
602
- placeholder="例如:基于当前分析,应该如何操作重点关注哪些风险?",
603
  lines=3
604
  )
605
 
 
 
606
  strategy_btn = gr.Button("生成策略", variant="primary")
607
 
608
  with gr.Column():
609
  strategy_output = gr.Textbox(
610
  label="AI交易策略建议",
611
- lines=15,
612
  interactive=False
613
  )
614
 
@@ -624,54 +934,46 @@ def create_interface():
624
 
625
  strategy_btn.click(
626
  platform.get_trading_strategy,
627
- inputs=[user_input],
628
  outputs=[strategy_output]
629
  )
630
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
631
  # 数学原理说明
632
  with gr.TabItem("📚 数学原理"):
633
- gr.Markdown("""
634
- ## 核心数学原理
635
-
636
- ### 1. 纤理论 (Fiber Bundle Theory)
637
- - **结构定义**: ξ = (E, π, B, F)
638
- - **基空间 B**: 观测因子 (VIX², RV)
639
- - **总空间 E**: 高维市场状态
640
- - **投影 π**: E → B 的降维映射
641
- - **VRP截面**: s_VRP(b) = VIX² - RV
642
-
643
- ### 2. Whitney嵌入定理
644
- - 保证2n维嵌入保留n维流形的所有微分结构
645
- - 提供因子设计的理论下限
646
-
647
- ### 3. 梯度动力学
648
- - **势函数**: U(b) = (VRP)²/2
649
- - **演化方程**: db/dt = -η∇U(b) + σdW
650
- - **李雅普诺夫稳定性**: V(t) ≤ V(0)e^(-αt)
651
-
652
- ### 4. SO(3)等变网络
653
- - 保持旋转对称性: f(g·x) = g·f(x)
654
- - 正交权重初始化
655
- - 群作用下的不变性
656
-
657
- ### 5. XPINNs域分解
658
- - 并行子域处理
659
- - 界面条件约束
660
- - 零曲率保证一致性
661
-
662
- ### 6. 因果VAR模型
663
- - 动态因果发现
664
- - Granger因果检验
665
- - 脉冲响应分析
666
  """)
667
 
668
  gr.Markdown("""
669
  ---
670
  ### 使用说明:
671
  1. 上传您的金融数据(CSV或Excel格式)
672
- 2. 系统自动进数学分析和因果发现
673
- 3. 训练XPINNs模习数据模式
674
- 4. 使用LLM生成基于数学原理的交易策略
675
 
676
  **注意**: 本系统仅供研究参考,不构成投资建议。
677
  """)
@@ -680,10 +982,10 @@ def create_interface():
680
 
681
  # 主函数
682
  if __name__ == "__main__":
683
- logger.info("启动港股智能分析平台...")
684
  interface = create_interface()
685
  interface.launch(
686
  server_name="0.0.0.0",
687
  server_port=7860,
688
  share=False
689
- )
 
2
  """
3
  港股智能分析平台 - Hugging Face Spaces版本
4
  集成数学原理的XPINNs训练与LLM推理系统
5
+ (已扩展:噪声分离、Whitney嵌入截面学习、梯度动力学模拟、LLM伪代码/日内策略)
6
  """
7
 
8
  import os
 
65
  def __init__(self, base_dim=2, fiber_dim=16):
66
  self.base_dim = base_dim # VIX^2, RV
67
  self.fiber_dim = fiber_dim # 隐藏状态维度
68
+ self.whitney_factor = 2 * fiber_dim # Whitney嵌入因子(论上)
69
 
70
  def project_to_base(self, high_dim_state):
71
  """投影到基空间"""
 
73
  high_dim_state = np.pad(high_dim_state, (0, self.fiber_dim - len(high_dim_state)))
74
 
75
  # 计算VIX^2代理
76
+ vix_squared = np.sum(high_dim_state[:self.fiber_dim//2]**2) / (self.fiber_dim//2 + 1e-12)
77
  # 计算实现波动率
78
  rv = np.std(high_dim_state[self.fiber_dim//2:])
79
 
 
84
  vix_squared, rv = base_point
85
  return vix_squared - rv
86
 
87
+ class NoiseExplorer:
88
+ """
89
+ 噪声分离与验证:基于 VIX^2 与 RV 的关系,尝试把观测上的噪声(纤维方向)与基空间信息分离。
90
+ 简单实现:对 VIX^2 与 RV 做线性回归,分析残差的统计特性(自相关、能量谱),并给出 VRP 统计摘要。
91
+ 以后可扩展为更严格的协整检验(Johansen / ADF)。
92
+ """
93
+ def __init__(self):
94
+ pass
95
+
96
+ def regress_vix2_vs_rv(self, vix2_series, rv_series):
97
+ # 简单线性回归:vix2 = a * rv + b
98
+ X = np.vstack([rv_series, np.ones_like(rv_series)]).T
99
+ try:
100
+ coef, _, _, _ = np.linalg.lstsq(X, vix2_series, rcond=None)
101
+ a, b = coef[0], coef[1]
102
+ preds = a * rv_series + b
103
+ resid = vix2_series - preds
104
+ return {
105
+ 'a': float(a), 'b': float(b),
106
+ 'preds': preds, 'resid': resid
107
+ }
108
+ except Exception as e:
109
+ return None
110
+
111
+ def resid_stats(self, resid):
112
+ # 基本残差统计:均值、方差、自相关(lag1)、能量谱(简单FFT)
113
+ mean = float(np.mean(resid))
114
+ var = float(np.var(resid))
115
+ if len(resid) > 2:
116
+ ac1 = float(np.corrcoef(resid[:-1], resid[1:])[0,1])
117
+ else:
118
+ ac1 = 0.0
119
+ # FFT能量谱主频
120
+ try:
121
+ fft = np.fft.rfft(resid - mean)
122
+ freqs = np.fft.rfftfreq(len(resid))
123
+ power = np.abs(fft)**2
124
+ dominant_idx = int(np.argmax(power[1:]) + 1) if len(power) > 1 else 0
125
+ dominant_freq = float(freqs[dominant_idx]) if len(freqs) > dominant_idx else 0.0
126
+ except:
127
+ dominant_freq = 0.0
128
+ return {'mean':mean, 'var':var, 'ac1':ac1, 'dominant_freq':dominant_freq}
129
+
130
+ def explore(self, df, vix2_col=None, rv_col=None):
131
+ # 自动寻找列名
132
+ numeric = df.select_dtypes(include=[np.number]).columns.tolist()
133
+ if vix2_col is None or rv_col is None:
134
+ # 尝试匹配
135
+ candidates = [c.lower() for c in numeric]
136
+ vix_col = None
137
+ rv_col_local = None
138
+ for c in numeric:
139
+ if 'vix' in c.lower():
140
+ vix_col = c
141
+ if 'rv' in c.lower() or 'realized' in c.lower():
142
+ rv_col_local = c
143
+ if vix_col is None or rv_col_local is None:
144
+ # 退回到前两列
145
+ if len(numeric) >= 2:
146
+ vix_col, rv_col_local = numeric[0], numeric[1]
147
+ else:
148
+ return None
149
+ vix2_col, rv_col = vix_col, rv_col_local
150
+
151
+ vix2 = df[vix2_col].fillna(method='ffill').values
152
+ rv = df[rv_col].fillna(method='ffill').values
153
+
154
+ reg = self.regress_vix2_vs_rv(vix2, rv)
155
+ if reg is None:
156
+ return None
157
+ stats = self.resid_stats(reg['resid'])
158
+ vrp_series = vix2 - reg['preds']
159
+ # 返回摘要
160
+ return {
161
+ 'vix2_col': vix2_col,
162
+ 'rv_col': rv_col,
163
+ 'reg_coeff': {'a':reg['a'], 'b':reg['b']},
164
+ 'resid_stats': stats,
165
+ 'vrp_mean': float(np.mean(vrp_series)),
166
+ 'vrp_std': float(np.std(vrp_series)),
167
+ 'vrp_series': vrp_series,
168
+ 'reg_pred': reg['preds'],
169
+ 'residuals': reg['resid']
170
+ }
171
+
172
+ class WhitneyEmbedder(nn.Module):
173
+ """
174
+ 基于 Whitney 嵌入思想的简单 autoencoder 与截面学习网络:
175
+ - autoencoder 用于学习从高维观测到低维(whitney_factor)的光滑嵌入
176
+ - section_net 将 base (VIX^2, RV) 映射回 fiber(截面估计),用于自演化/再构造
177
+ """
178
+ def __init__(self, input_dim=64, fiber_dim=16, device='cpu'):
179
+ super().__init__()
180
+ self.device = device
181
+ self.fiber_dim = fiber_dim
182
+ self.whitney_dim = 2 * fiber_dim # 推荐维度
183
+ # encoder / decoder
184
+ self.encoder = nn.Sequential(
185
+ nn.Linear(input_dim, 128),
186
+ nn.ReLU(),
187
+ nn.Linear(128, self.whitney_dim)
188
+ )
189
+ self.decoder = nn.Sequential(
190
+ nn.Linear(self.whitney_dim, 128),
191
+ nn.ReLU(),
192
+ nn.Linear(128, input_dim)
193
+ )
194
+ # 截面学习网络:从 base (2维) -> fiber_dim
195
+ self.section_net = nn.Sequential(
196
+ nn.Linear(2, 32),
197
+ nn.ReLU(),
198
+ nn.Linear(32, fiber_dim)
199
+ )
200
+ self.to(self.device)
201
+
202
+ def forward(self, x):
203
+ z = self.encoder(x)
204
+ recon = self.decoder(z)
205
+ return z, recon
206
+
207
+ def learn_section(self, base_points):
208
+ """
209
+ 给定 base_points (N x 2),输出 fiber 估计(N x fiber_dim)
210
+ 这是一个直接前向调用(训练通过 train_embedding 来执行)
211
+ """
212
+ with torch.no_grad():
213
+ x = torch.tensor(base_points, dtype=torch.float32, device=self.device)
214
+ return self.section_net(x).cpu().numpy()
215
+
216
+ class GradientDynamics:
217
+ """
218
+ 把势函数 U(b) 的梯度流当成市场的动力路径:db = -eta * grad U(b) dt + sigma dW
219
+ - 能把离散梯度下降(epochs 步)映射为连续路径的模拟
220
+ - 使用 torch 自动求导对 U 做梯度(U可以是任意torch可微函数)
221
+ """
222
+ def __init__(self, eta=0.1, sigma=0.01, device='cpu'):
223
+ self.eta = eta
224
+ self.sigma = sigma
225
+ self.device = device
226
+
227
+ def U_vrp(self, b):
228
+ """
229
+ 默认势函数:U(b) = (VRP)^2 / 2 ,其中 b = [vix2, rv]
230
+ b 为 torch.tensor shape (..., 2)
231
+ """
232
+ vix2 = b[...,0]
233
+ rv = b[...,1]
234
+ vrp = vix2 - rv
235
+ return 0.5 * vrp**2
236
+
237
+ def grad_U(self, b):
238
+ b_t = torch.tensor(b, dtype=torch.float32, requires_grad=True, device=self.device)
239
+ U = self.U_vrp(b_t).sum()
240
+ U.backward()
241
+ grad = b_t.grad.detach().cpu().numpy()
242
+ return grad
243
+
244
+ def simulate_flow(self, b0, T=1.0, dt=0.01, seed=None):
245
+ """
246
+ Euler-Maruyama 模拟:
247
+ b0: 初始点 (2,)
248
+ 返回路径 (Nsteps+1, 2)
249
+ """
250
+ if seed is not None:
251
+ np.random.seed(seed)
252
+ n_steps = int(T / dt)
253
+ path = np.zeros((n_steps+1, 2))
254
+ path[0] = np.array(b0, dtype=float)
255
+ for i in range(n_steps):
256
+ b_cur = path[i]
257
+ grad = self.grad_U(b_cur)
258
+ db_det = - self.eta * grad
259
+ db_stoch = self.sigma * np.sqrt(dt) * np.random.randn(2)
260
+ path[i+1] = b_cur + db_det * dt + db_stoch
261
+ return path
262
+
263
  class EquivariantLayer(nn.Module):
264
  """SO(3)等变层"""
265
 
 
407
  class MathematicalTrainer:
408
  """数学原理驱动的训练器"""
409
 
410
+ def __init__(self, device='cpu'):
411
+ self.device = device
412
+ self.fiber_bundle = FiberBundleTheory(fiber_dim=config.FIBER_BUNDLE_DIM)
413
+ self.causal_var = CausalVAR(max_lag=config.CAUSAL_LAG)
414
  self.model = XPINNsGenerator()
415
  self.optimizer = Adam(self.model.parameters(), lr=0.001)
416
  self.scaler = StandardScaler()
417
+ # 新增:
418
+ self.noise_explorer = NoiseExplorer()
419
+ self.embedder = None # lazy init
420
+ self.gradient_dynamics = GradientDynamics(eta=0.5, sigma=0.02, device=device)
421
 
422
  def prepare_data(self, df):
423
  """准备训练数据"""
 
506
  logger.info(f"Epoch {epoch}: Loss = {avg_loss:.6f}")
507
 
508
  return losses
509
+
510
+ # ---------- 新增:嵌入器训练接口 ----------
511
+ def init_embedder(self, input_dim=64):
512
+ if self.embedder is None:
513
+ self.embedder = WhitneyEmbedder(input_dim=input_dim, fiber_dim=self.fiber_bundle.fiber_dim, device=self.device)
514
+
515
+ def train_embedding(self, X_np, epochs=100, lr=1e-3):
516
+ """
517
+ 训练 autoencoder,X_np: numpy array (N, input_dim)
518
+ """
519
+ self.init_embedder(input_dim=X_np.shape[1])
520
+ model = self.embedder
521
+ opt = Adam(model.parameters(), lr=lr)
522
+ X = torch.tensor(X_np, dtype=torch.float32, device=self.device)
523
+ for epoch in range(epochs):
524
+ opt.zero_grad()
525
+ z, recon = model(X)
526
+ loss = F.mse_loss(recon, X) # 重构损失
527
+ loss.backward()
528
+ opt.step()
529
+ if epoch % 20 == 0:
530
+ logger.info(f"[Embedder] Epoch {epoch}, recon loss {loss.item():.6f}")
531
+ return loss.item()
532
+
533
+ def explore_noise(self, df, vix2_col=None, rv_col=None):
534
+ return self.noise_explorer.explore(df, vix2_col=vix2_col, rv_col=rv_col)
535
+
536
+ def simulate_gradient_flow(self, initial_base_point, T=1.0, dt=0.01):
537
+ return self.gradient_dynamics.simulate_flow(initial_base_point, T=T, dt=dt)
538
 
539
  class LLMInterface:
540
  """LLM接口"""
 
551
  "inputs": prompt,
552
  "parameters": {
553
  "max_new_tokens": max_length,
554
+ "temperature": 0.3,
555
  "top_p": 0.9,
556
  "do_sample": True
557
  }
 
569
  except Exception as e:
570
  return f"错误: {str(e)}"
571
 
572
+ def _pseudocode_template(self, strategy_spec: Dict[str,Any]) -> str:
573
+ """
574
+ 当LLM不可用时返回一个确性的伪代码结构
575
+ strategy_spec 包含:entry_rule, exit_rule, position_sizing, risk_params
576
+ """
577
+ template = f"""# PSEUDOCODE for intraday quant strategy
578
+ # Entry: {strategy_spec.get('entry_rule','待定')}
579
+ # Exit: {strategy_spec.get('exit_rule','待定')}
580
+ # Position sizing: {strategy_spec.get('position_sizing','固定仓位/比例')}
581
+ # Risk: {strategy_spec.get('risk_params','默认')}
582
+ def on_bar(bar):
583
+ features = compute_features(bar) # e.g. VRP, momentum, spread
584
+ signal = 0
585
+ if {strategy_spec.get('entry_condition_code','False')}:
586
+ signal = 1
587
+ entry_price = bar.close
588
+ size = determine_size(entry_price)
589
+ if {strategy_spec.get('exit_condition_code','False')}:
590
+ signal = -1
591
+ manage_risk()
592
+ execute(signal, size)
593
+ """
594
+ return template
595
+
596
+ def analyze_trading(self, analysis_results, market_data, intraday=False, generate_pseudocode=False):
597
+ """分析交易策略,扩展:日内与伪代码生成"""
598
+ prompt = f"""你是一个量化交易与日内交易专家。请基于以下数学分析结果和市场数据生成可操作的交易策略。
599
+
600
+ 数学分析摘要:
601
+ {json.dumps(analysis_results, indent=2)}
602
 
603
  市场数据摘要:
604
  {market_data}
605
 
606
+ 给出
607
+ 1) 简洁策略描述(入场、止损、止盈、仓管理)
608
+ 2) 若为日内(intraday=True),请给出明确定义的入场/退出信号(基于短周期,例如1-5分钟或tick),并说明延迟/滑点考虑
609
+ 3) 风险控制与回测建议(数据频率、回测窗口)
610
+ 4) 若要求generate_pseudocode=True,请以伪代码形式输出策略实现模板(明确函数名、输入特征、信号判断、止损/止盈逻辑)
611
 
612
+ 格式:
613
+ - 段落 1: 策略概览
614
+ - 段落 2: 规则要点(枚举)
615
+ - 段落 3: 伪代码(如果要求)
616
 
617
+ 请尽量简洁、直接给出可执行的建议。
618
+ """
619
+ if generate_pseudocode:
620
+ prompt += "\n请在伪代码中包含:compute_features(), determine_size(), execute() 等函数签名。\n"
621
+ # 调用LLM
622
+ llm_resp = self.query(prompt, max_length=800)
623
+ # 如果返回是错误或API失败,fallback到确定性伪代码
624
+ if isinstance(llm_resp, str) and llm_resp.startswith("错误") or "API调用失败" in str(llm_resp):
625
+ # 构造简单策略说明
626
+ strategy_spec = {
627
+ 'entry_rule': '当 VRP 从负值上穿其短期均值且短期动量为正时买入',
628
+ 'exit_rule': '亏损超过止损点或达到止盈点或VRP反转',
629
+ 'position_sizing': '账户风险百分比方式(例如每单最大亏损 0.5%)',
630
+ 'risk_params': '止损与仓位受限,滑点假设 0.02%',
631
+ 'entry_condition_code': 'features["vrp"] > features["vrp_sma_short"] and features["mom"] > 0',
632
+ 'exit_condition_code': 'price <= entry_price*(1 - stop_loss_pct) or price >= entry_price*(1 + take_profit_pct)'
633
+ }
634
+ fallback = "LLM不可用,返回内置伪代码模板。\n\n" + self._pseudocode_template(strategy_spec)
635
+ return fallback
636
+ return llm_resp
637
+
638
  class TradingPlatform:
639
  """主交易平台"""
640
 
641
+ def __init__(self, device='cpu'):
642
+ self.trainer = MathematicalTrainer(device=device)
643
  self.llm = LLMInterface()
644
  self.current_data = None
645
  self.analysis_results = {}
 
727
  except Exception as e:
728
  return f"训练失败: {str(e)}", None
729
 
730
+ def run_noise_exploration(self):
731
+ """运行噪声探索(基于 VIX^2 vs RV 回归)"""
732
+ if self.current_data is None:
733
+ return "请先上传数据", None
734
+ try:
735
+ res = self.trainer.explore_noise(self.current_data)
736
+ if res is None:
737
+ return "未找到合适的数值列进行噪声探索", None
738
+ summary = f"噪声探索结果: VRP 均值 {res['vrp_mean']:.6f}, VRP std {res['vrp_std']:.6f}, 残差自相关(1) {res['resid_stats']['ac1']:.4f}"
739
+ return summary, res
740
+ except Exception as e:
741
+ return f"噪声探索失败: {str(e)}", None
742
+
743
+ def train_embedding(self, epochs=100):
744
+ """训练 Whitney 嵌入(autoencoder)"""
745
+ if self.current_data is None:
746
+ return "请先上传数据", None
747
+ try:
748
+ # 复用之前prepare_data的X构造方式,得到特征矩阵
749
+ X, y, causal = self.trainer.prepare_data(self.current_data)
750
+ if X is None:
751
+ return "数据不足以训练嵌入", None
752
+ X_np = X.numpy()
753
+ final_loss = self.trainer.train_embedding(X_np, epochs=epochs)
754
+ return f"嵌入训练完成, 最终重构损失 {final_loss:.6f}", None
755
+ except Exception as e:
756
+ return f"嵌入训练失败: {str(e)}", None
757
+
758
+ def simulate_dynamics(self, start_vix2=1.0, start_rv=0.8, T=1.0, dt=0.01):
759
+ """模拟梯度动力学路径"""
760
+ try:
761
+ path = self.trainer.simulate_gradient_flow([start_vix2, start_rv], T=T, dt=dt)
762
+ return f"模拟完成,路径长度 {len(path)}", path
763
+ except Exception as e:
764
+ return f"模拟失败: {str(e)}", None
765
+
766
+ def get_trading_strategy(self, user_question, intraday=False, generate_pseudocode=False, model_name=None):
767
  """获取交易策略"""
768
  if not self.analysis_results:
769
  return "请先上传并分析数据"
 
774
  if self.current_data is not None:
775
  numeric_cols = self.current_data.select_dtypes(include=[np.number]).columns
776
  if len(numeric_cols) > 0:
777
+ latest_data = self.current_data[numeric_cols].tail(20).describe()
778
  market_summary = latest_data.to_string()
779
 
780
  # 合并用户问题
781
  full_prompt = f"{user_question}\n\n当前分析结果:{json.dumps(self.analysis_results, indent=2)}\n\n市场数据:{market_summary}"
782
 
783
+ # 更新llm模型(可选)
784
+ if model_name:
785
+ self.llm = LLMInterface(model_name)
786
+
787
  # 获取LLM回复
788
+ response = self.llm.analyze_trading(self.analysis_results, full_prompt, intraday=intraday, generate_pseudocode=generate_pseudocode)
789
 
790
  return response
791
 
 
798
 
799
  with gr.Blocks(title="港股智能分析平台", theme=gr.themes.Soft()) as interface:
800
  gr.Markdown("""
801
+ # 🚀 港股智能分析平台 - 数学原理驱动(扩展版)
802
+
803
+ 新增功能
804
+ - 噪声分离 / VRP 残差分析
805
+ - 基于 Whitney 嵌入的 autoencoder 与截面学习
806
+ - 梯度动力学(将梯度下降视作连续演化)模拟
807
+ - LLM 支持日内策略与伪代码输出(集/回退模板)
 
808
  """)
809
 
810
  with gr.Tabs():
 
840
  outputs=[data_summary, analysis_result, status_text]
841
  )
842
 
843
+ # 噪声探索与嵌入训练
844
+ with gr.TabItem("🔍 噪声探索 & 嵌入"):
845
+ with gr.Row():
846
+ with gr.Column():
847
+ noise_btn = gr.Button("运行噪声探索 (VIX^2 vs RV)", variant="primary")
848
+ noise_summary = gr.Textbox(label="噪声探索摘要", lines=4, interactive=False)
849
+ noise_details = gr.JSON(label="噪声探索详细结果", visible=False)
850
+ embed_epochs = gr.Slider(minimum=20, maximum=500, value=100, step=20, label="嵌入训练轮数")
851
+ embed_btn = gr.Button("训练 Whitney 嵌��", variant="primary")
852
+ embed_status = gr.Textbox(label="嵌入训练状态", lines=2, interactive=False)
853
+
854
+ with gr.Column():
855
+ embed_plot = gr.Plot(label="嵌入(可视化)", visible=False)
856
+
857
+ noise_btn.click(platform.run_noise_exploration, inputs=[], outputs=[noise_summary, noise_details])
858
+ embed_btn.click(platform.train_embedding, inputs=[embed_epochs], outputs=[embed_status, embed_plot])
859
+
860
  # 模型训练标签
861
  with gr.TabItem("🧮 XPINNs模型训练"):
862
  with gr.Row():
 
887
  # 交易策略标签
888
  with gr.TabItem("💹 智能交易策略"):
889
  gr.Markdown("""
890
+ ### 基于数学原理的交易策略生成(扩展)
891
 
892
  系统将结合:
893
  - 纤维丛投影的市场状态
894
  - 因果VAR的动态关系
895
+ - 梯度动力学的演化模拟
896
+ - LLM智能推理(可输出伪代码)
 
 
897
  """)
898
 
899
  with gr.Row():
 
907
 
908
  user_input = gr.Textbox(
909
  label="交易问题",
910
+ placeholder="例如:基于当前分析,的日内策略如何构造请给出伪代码。",
911
  lines=3
912
  )
913
 
914
+ intraday_check = gr.Checkbox(label="日内策略 (intraday)", value=True)
915
+ pseudocode_check = gr.Checkbox(label="生成伪代码", value=True)
916
  strategy_btn = gr.Button("生成策略", variant="primary")
917
 
918
  with gr.Column():
919
  strategy_output = gr.Textbox(
920
  label="AI交易策略建议",
921
+ lines=20,
922
  interactive=False
923
  )
924
 
 
934
 
935
  strategy_btn.click(
936
  platform.get_trading_strategy,
937
+ inputs=[user_input, intraday_check, pseudocode_check, model_dropdown],
938
  outputs=[strategy_output]
939
  )
940
 
941
+ # 梯度动力学模拟
942
+ with gr.TabItem("⚙️ 梯度动力学模拟"):
943
+ with gr.Row():
944
+ with gr.Column():
945
+ start_vix2 = gr.Number(value=1.0, label="初始 VIX^2")
946
+ start_rv = gr.Number(value=0.8, label="初始 RV")
947
+ T = gr.Number(value=1.0, label="模拟总时间 T")
948
+ dt = gr.Number(value=0.01, label="时间步长 dt")
949
+ sim_btn = gr.Button("运行模拟", variant="primary")
950
+ sim_result = gr.Textbox(label="模拟结果", lines=3, interactive=False)
951
+ with gr.Column():
952
+ sim_plot = gr.Plot(label="模拟路径 (VIX^2, RV)")
953
+
954
+ sim_btn.click(
955
+ platform.simulate_dynamics,
956
+ inputs=[start_vix2, start_rv, T, dt],
957
+ outputs=[sim_result, sim_plot]
958
+ )
959
+
960
  # 数学原理说明
961
  with gr.TabItem("📚 数学原理"):
962
+ gr.Markdown(f"""
963
+ ## 核心数学原理(参考:你的笔记与论文)
964
+ - 纤维丛理论与VRP截面:参见上传的改进文档(BKKK改进)。:contentReference[oaicite:3]{index=3}
965
+ - Whitney嵌入定理与光滑嵌入:作为嵌入度上限的理论依据。:contentReference[oaicite:4]{index=4}
966
+ - 等变网络与XPINNs:关于等变与几何保证的更系统论文。:contentReference[oaicite:5]{index=5}
967
+ - 梯度动力学视角:梯度下降路径看作系统的演化路径、可扩展到SDE与Fokker-Planck 表述。:contentReference[oaicite:6]{index=6}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
968
  """)
969
 
970
  gr.Markdown("""
971
  ---
972
  ### 使用说明:
973
  1. 上传您的金融数据(CSV或Excel格式)
974
+ 2. 噪声探索以获得 VRP/残差统计
975
+ 3. 训练嵌入 / XPINNs拟梯度动力
976
+ 4. 使用 LLM 生成日内/量化策略并选择是否输出伪代码
977
 
978
  **注意**: 本系统仅供研究参考,不构成投资建议。
979
  """)
 
982
 
983
  # 主函数
984
  if __name__ == "__main__":
985
+ logger.info("启动港股智能分析平台(扩展版)...")
986
  interface = create_interface()
987
  interface.launch(
988
  server_name="0.0.0.0",
989
  server_port=7860,
990
  share=False
991
+ )