1oscon commited on
Commit
88e9ec1
·
verified ·
1 Parent(s): c1735b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -29
app.py CHANGED
@@ -10,6 +10,18 @@ import importlib
10
  import random
11
  from datetime import datetime
12
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # ========== 路径修复与导入别名(修复 from 策略基类 import 策略接口) ==========
14
  def _修复导入路径与别名():
15
  root = os.path.dirname(os.path.abspath(__file__))
@@ -212,39 +224,49 @@ except Exception:
212
  配置模块 = None
213
 
214
  # ========== Gradio 界面 ==========
215
- with gr.Blocks(title="模拟实盘(OKX 公共WS + 多策略引擎)") as demo:
216
- gr.Markdown("# 📈 模拟实盘(订阅OKX公共行情 聚合K线 → 策略 → 纸上交易所)")
217
- gr.Markdown("提示:点击右上“⚙️ 设置”可进入配置页(上传CSV、参数加载/保存);若后端模块缺失将自动进入演示引擎。")
218
 
219
- # 页面切换容器
220
- with gr.Group(visible=True) as 运行面板:
221
- with gr.Row():
222
- with gr.Column(scale=1):
223
- 合约输入 = gr.Textbox(label="合约ID", value="UXLINK-USDT-SWAP", placeholder="例:BTC-USDT-SWAP / ETH-USDT-SWAP")
224
- 周期选择 = gr.Radio(label="周期(分钟)", choices=["30", "60", "120", "240"], value="60")
225
- 参数输入 = gr.Textbox(label="策略参数(JSON)", value=json.dumps(默认参数, ensure_ascii=False, indent=2), lines=12)
226
  with gr.Row():
227
- 启动按钮 = gr.Button("🚀 启动模拟", variant="primary")
228
- 停止按钮 = gr.Button("⏹️ 停止模拟", variant="stop")
229
- 刷新按钮 = gr.Button("🔄 刷新状态")
230
- 设置按钮 = gr.Button("⚙️ 设置", variant="secondary")
231
- with gr.Column(scale=1):
232
- 状态显示 = gr.Textbox(label="运行状态", lines=1, interactive=False)
233
- 日志显示 = gr.Textbox(label="实时日志(最近120行)", lines=22, interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
- with gr.Group(visible=False) as 设置面板:
236
- 返回按钮 = gr.Button(" 返回运行页", variant="secondary")
237
- gr.Markdown("## 设置面板")
238
- if 配置模块 is not None:
239
- # 构建设置面板(来自配置.py),返回关键组件用于与运行页联动
240
- 构件 = 配置模块.构建设置面板(容器=设置面板, 默认参数=默认参数, 记录函数=_记录)
241
- # 可选:从设置面板“一键回填到运行页”
242
- if isinstance(构件, dict) and "参数编辑框" in 构件 and "复制按钮" in 构件:
243
- 构件["复制按钮"].click(lambda s: s, inputs=构件["参数编辑框"], outputs=参数输入)
244
- else:
245
- gr.Markdown("未找到 配置.py,无法加载设置面板。")
246
 
247
- # 事件绑定(页面切换)
248
  设置按钮.click(lambda: (gr.update(visible=False), gr.update(visible=True)), outputs=[运行面板, 设置面板])
249
  返回按钮.click(lambda: (gr.update(visible=True), gr.update(visible=False)), outputs=[运行面板, 设置面板])
250
 
 
10
  import random
11
  from datetime import datetime
12
 
13
+ # ========== 主题与样式 ==========
14
+ theme = gr.themes.Soft()
15
+ css = """
16
+ #topbar { display:flex; align-items:center; justify-content:space-between;
17
+ padding:10px 14px; background:linear-gradient(90deg,#0f172a,#1f2937); color:#fff;
18
+ border-radius:14px; margin-bottom:10px }
19
+ #topbar h1 { font-size:18px; margin:0; font-weight:700 }
20
+ #topbar .right { display:flex; gap:8px; align-items:center }
21
+ .badge { padding:2px 8px; border-radius:999px; background:#10b981; color:#052e22; font-weight:700 }
22
+ .footer-note { opacity:.7; font-size:12px; }
23
+ """
24
+
25
  # ========== 路径修复与导入别名(修复 from 策略基类 import 策略接口) ==========
26
  def _修复导入路径与别名():
27
  root = os.path.dirname(os.path.abspath(__file__))
 
224
  配置模块 = None
225
 
226
  # ========== Gradio 界面 ==========
227
+ with gr.Blocks(title="模拟实盘(OKX 公共WS + 多策略引擎)", theme=theme, css=css) as demo:
228
+ gr.HTML('<div id="topbar"><h1>📈 模拟实盘</h1><div class="right"><span class="badge">OKX Public WS</span></div></div>')
229
+ gr.Markdown("提示:点击“⚙️ 设置”进入配置页(上传CSV、参数加载/保存)。若后端模块缺失将自动进入演示引擎。")
230
 
231
+ with gr.Row():
232
+ with gr.Column(scale=7):
233
+ with gr.Group(visible=True) as 运行面板:
 
 
 
 
234
  with gr.Row():
235
+ with gr.Column(scale=1):
236
+ 合约输入 = gr.Textbox(label="合约ID", value="UXLINK-USDT-SWAP", placeholder="例:BTC-USDT-SWAP / ETH-USDT-SWAP")
237
+ 周期选择 = gr.Radio(label="周期(分钟)", choices=["30", "60", "120", "240"], value="60")
238
+ 参数输入 = gr.Textbox(label="策略参数(JSON)", value=json.dumps(默认参数, ensure_ascii=False, indent=2), lines=12)
239
+ with gr.Row():
240
+ 启动按钮 = gr.Button("🚀 启动模拟", variant="primary")
241
+ 停止按钮 = gr.Button("⏹️ 停止模拟", variant="stop")
242
+ 刷新按钮 = gr.Button("🔄 刷新状态")
243
+ 设置按钮 = gr.Button("⚙️ 设置", variant="secondary")
244
+ with gr.Column(scale=1):
245
+ 状态显示 = gr.Textbox(label="运行状态", lines=2, interactive=False)
246
+ 日志显示 = gr.Textbox(label="实时日志(最近120行)", lines=22, interactive=False)
247
+
248
+ with gr.Group(visible=False) as 设置面板:
249
+ 返回按钮 = gr.Button("← 返回运行页", variant="secondary")
250
+ gr.Markdown("## 设置")
251
+ if 配置模块 is not None:
252
+ 构件 = 配置模块.构建设置面板(容器=设置面板, 默认参数=默认参数, 记录函数=_记录)
253
+ if isinstance(构件, dict):
254
+ # 参数回填
255
+ if "参数编辑框" in 构件 and ("复制按钮" in 构件 or "复制参数按钮" in 构件):
256
+ 回填参数按钮 = 构件.get("复制按钮") or 构件.get("复制参数按钮")
257
+ 回填参数按钮.click(lambda s: s, inputs=构件["参数编辑框"], outputs=参数输入)
258
+ # 合约回填
259
+ if "回填合约按钮" in 构件 and "合约ID框" in 构件:
260
+ 构件["回填合约按钮"].click(lambda s: s.strip(), inputs=构件["合约ID框"], outputs=合约输入)
261
+ else:
262
+ gr.Markdown("未找到 配置.py,无法加载设置面板。")
263
 
264
+ with gr.Column(scale=5):
265
+ gr.Markdown("### 使用说明")
266
+ gr.Markdown("- 在设置页上传CSV并完成列映射与合约登记\n- 将参数与合约一键回填到运行页\n- 启动后可在右侧查看状态和日志\n- 空闲时 Space 会休眠,策略不会持续运行(演示环境)")
267
+ gr.Markdown("<div class='footer-note'>Tips: 持久化运行请在自有服务器部署引擎,Space 仅作前端/演示。</div>")
 
 
 
 
 
 
 
268
 
269
+ # 页面切换
270
  设置按钮.click(lambda: (gr.update(visible=False), gr.update(visible=True)), outputs=[运行面板, 设置面板])
271
  返回按钮.click(lambda: (gr.update(visible=True), gr.update(visible=False)), outputs=[运行面板, 设置面板])
272