🇨🇳 简体中文
🇺🇸 English
🇯🇵 日本語
Skip to the content.

Frontend 模块架构文档

本文档描述 Frontend(前端)模块的架构设计、组件结构、状态管理和技术栈。

概述

Frontend 模块是 Fire 量化交易系统的用户界面层,采用 React 18 + TypeScript 5 + Semi Design 技术栈,提供响应式的单页应用体验。系统采用组件化架构,通过 Context API 进行状态管理,支持实时数据展示、交互式交易操作和多维度数据可视化。

核心功能

交易管理界面

数据可视化

系统管理界面

技术架构

组件

架构分层图

graph TB
    subgraph "展示层"
        Pages[页面组件]
        Components[公共组件]
        Charts[图表组件]
    end

    subgraph "状态层"
        AuthCtx[AuthContext<br/>认证状态]
        WSCtx[WebSocketContext<br/>实时连接]
        ChCtx[ChannelContext<br/>通道状态]
    end

    subgraph "服务层"
        API[API Service<br/>接口封装]
        WS[WebSocket Service<br/>实时通信]
        Utils[Utils<br/>工具函数]
    end

    subgraph "基础设施"
        Router[React Router<br/>路由管理]
        Config[Config<br/>配置管理]
        Types[TypeScript<br/>类型定义]
    end

    Pages --> Components
    Pages --> Charts
    Pages --> AuthCtx
    Pages --> WSCtx
    Pages --> ChCtx

    AuthCtx --> API
    WSCtx --> WS
    ChCtx --> API

    API --> Utils
    WS --> Utils

    Router --> Pages
    Config --> API
    Types --> Pages

    style Pages fill:#e1f5ff
    style AuthCtx fill:#e8f5e9
    style API fill:#fff4e6

核心组件说明

Layout (布局组件)

AuthContext (认证上下文)

WebSocketContext (WebSocket 上下文)

ChannelContext (通道上下文)

FlowEditor (可视化流程编辑器)

依赖关系

内部依赖

模块名 用途 是否必需
services/api API 接口封装
utils/apiClient HTTP 客户端
config/strategySchemas 策略配置模式
hooks/useAuth 认证 Hook
components/* 公共组件

外部依赖

库名 版本要求 用途 License
react ^18.2.0 UI 框架 MIT
typescript ^5.0.0 类型系统 Apache 2.0
@douyinfe/semi-ui ^2.50.0 UI 组件库 MIT
react-router-dom ^6.14.0 路由管理 MIT
axios ^1.4.0 HTTP 请求 MIT
echarts ^5.4.0 图表库 Apache 2.0
vite ^4.4.0 构建工具 MIT

数据流

认证流程

sequenceDiagram
    participant User as 用户
    participant Login as 登录页
    participant Auth as AuthContext
    participant API as API服务
    participant Router as 路由

    User->>Login: 输入凭据
    Login->>API: 发送登录请求
    API-->>Login: 返回Token和用户信息
    Login->>Auth: 调用login()
    Auth->>Auth: 保存Token到localStorage
    Auth->>Auth: 更新user状态
    Auth-->>Router: 触发重新渲染
    Router->>Router: 跳转到主页

WebSocket 消息流

flowchart LR
    Server([服务端]) --> WS[WebSocket]
    WS --> Context[WebSocketContext]
    Context --> Parse[解析消息]
    Parse --> Type{消息类型}

    Type -->|行情| Market[行情处理]
    Type -->|交易| Trade[交易处理]
    Type -->|日志| Log[日志处理]
    Type -->|进度| Progress[进度处理]

    Market --> Update1[更新行情组件]
    Trade --> Update2[更新持仓组件]
    Log --> Update3[更新日志组件]
    Progress --> Update4[更新进度条]

    style Context fill:#e1f5ff
    style Parse fill:#fff4e6

数据结构

用户模型

interface User {
  id: string;
  username: string;
  email: string;
  user_type: 'admin' | 'user';
  status: 'active' | 'inactive';
  created_at: string;
  updated_at: string;
}

交易会话模型

interface TradingSession {
  id: string;
  name: string;
  mode: 'backtest' | 'simulation' | 'live';
  status: 'pending' | 'running' | 'paused' | 'completed' | 'error';
  config: SessionConfig;
  channels: ChannelConfig[];
  performance: PerformanceMetrics;
  created_at: string;
  started_at?: string;
  ended_at?: string;
}

WebSocket 消息格式

interface WSMessage {
  type: 'market' | 'trade' | 'log' | 'progress' | 'status';
  task_id?: string;
  timestamp: string;
  data: any;
}

Flow Editor 数据模型

// Flow 节点定义
interface FlowNode {
  id: string;
  type: 'strategy' | 'output' | 'strategyGroup' | 'groupExit';
  position: { x: number; y: number };
  parentId?: string;                    // 策略节点所属的策略组 ID
  extent?: 'parent';                    // 限制在父节点内移动
  data: StrategyNodeData | OutputNodeData | StrategyGroupNodeData | GroupExitNodeData;
}

// 策略节点数据
interface StrategyNodeData {
  strategyId: string;
  strategyName: string;
  displayName?: string;
  category: 'Momentum' | 'Trend' | 'MeanReversion' | 'Volume' | 'Volatility';
  weight: number;              // 0.0 ~ 1.0
  parameters: Record<string, any>;
}

// 输出节点数据
interface OutputNodeData {
  label: string;
  votingMethod: 'weighted' | 'majority';
}

// 策略组节点数据 (UX Upgrade 新增)
interface StrategyGroupNodeData {
  groupId: string;
  groupName: string;
  groupWeight: number;           // 0 ~ 100 (整数百分比)
  groupColor: string;            // 边框颜色
  groupColorIndex: number;       // 8 色循环索引 (C1)
  autoLayoutEnabled: boolean;    // 自动布局开关 (C2)
}

// 策略组出口节点数据 (UX Upgrade 新增)
interface GroupExitNodeData {
  groupId: string;
  label: string;                 // "⚡"
}

// Flow 边定义
interface FlowEdge {
  id: string;
  source: string;
  target: string;
  type: 'default' | 'step' | 'smoothstep';
  animated?: boolean;
  label?: string;
}

// 通道 Flow 状态
interface ChannelFlowState {
  channelId: string;
  channelName: string;
  channelType: 'aggressive' | 'balanced' | 'conservative';
  capitalAllocation: number;   // 0.0 ~ 1.0
  enabled: boolean;
  nodes: FlowNode[];
  edges: FlowEdge[];
}

// 完整后端通道配置 (用于 JSON 编辑器)
interface BackendChannelConfig {
  channel_id: string;
  channel_name: string;
  channel_type: 'aggressive' | 'balanced' | 'conservative';
  capital_allocation: number;
  enabled: boolean;
  strategy_groups: {
    group_name: string;
    group_weight: number;      // 0.0 ~ 1.0
    strategies: {
      strategy_id: string;
      weight: number;
      parameters: Record<string, any>;
    }[];
  }[];
  voting_config: {
    intra_group_threshold: number;
    inter_group_threshold: number;
    min_confidence: number;
  };
  risk_limits: {
    max_loss_per_trade: number;
    max_daily_loss: number;
    max_drawdown: number;
    leverage_limit: number;
  };
  trading_rules: {
    max_positions: number;
    position_sizing_method: string;
    min_trade_size: number;
    max_trade_size: number;
    trading_hours: {
      start: string;
      end: string;
      timezone: string;
    };
  };
  time_granularity_weights: Record<string, number>;
}

// 策略元数据(从后端获取)
interface StrategyMetadata {
  strategy_id: string;
  display_name: string;
  description: string;
  category: string;
  parameters: ParameterDefinition[];
}

// 参数定义
interface ParameterDefinition {
  name: string;
  displayName?: string;
  type: 'number' | 'boolean' | 'string' | 'enum';
  default: any;
  min?: number;
  max?: number;
  options?: string[];         // for enum type
  description?: string;
  required?: boolean;
}

// 自定义模板
interface CustomTemplate {
  id: string;
  user_id: string;
  template_name: string;
  description?: string;
  channels_config: ChannelFlowState[];
  created_at: string;
  updated_at: string;
}

接口

路由配置

路径 组件 权限 说明
/login Login 公开 登录页
/assets Assets 需登录 资产管理
/trading/list TradingList 需登录 交易列表
/trading/detail/:id TradingDetail 需登录 交易详情
/trading/live/start LiveStart 需登录 实盘交易启动
/trading/simulation/start SimulationStart 需登录 模拟交易启动
/trading/backtest/start BacktestStart 需登录 回测交易启动
/channels/:id Channels 需登录 通道管理
/strategies/management StrategyManagement 需登录 策略管理列表
/strategies/management/:id StrategyEdit 需登录 策略编辑详情
/strategies/analysis IndicatorList 需登录 技术指标列表
/strategies/analysis/:id IndicatorDetail 需登录 技术指标详情
/data/import-data ImportData 需登录 数据导入
/settings Settings 需登录 系统设置
/settings/user-management UserManagement 管理员 用户管理

API 服务封装

// API 服务接口
export const api = {
  // 认证相关
  auth: {
    login: (credentials: LoginForm) => Promise<LoginResponse>,
    logout: () => Promise<void>,
    refresh: () => Promise<TokenResponse>
  },

  // 交易相关
  trading: {
    list: (params?: ListParams) => Promise<TradingSession[]>,
    create: (config: SessionConfig) => Promise<TradingSession>,
    start: (id: string) => Promise<void>,
    pause: (id: string) => Promise<void>,
    stop: (id: string) => Promise<void>
  },

  // 数据相关
  data: {
    import: (file: File, config: ImportConfig) => Promise<ImportResult>,
    query: (params: QueryParams) => Promise<MarketData[]>
  }
};

扩展点

自定义策略配置组件

// 扩展策略配置表单
import { StrategyConfigForm } from '@/components/StrategyConfig';

interface CustomStrategyConfigProps {
  strategy: Strategy;
  onChange: (config: any) => void;
}

export function CustomStrategyConfig({ strategy, onChange }: CustomStrategyConfigProps) {
  // 实现自定义策略配置组件
  // 返回配置表单UI
}

自定义图表组件

// 扩展图表组件
import { BaseChart } from '@/components/Charts';

interface CustomChartProps {
  data: any[];
  config: ChartConfig;
}

export function CustomChart({ data, config }: CustomChartProps) {
  // 实现自定义图表组件
  // 返回ECharts配置

  return <BaseChart option={option} />;
}

Hooks 系统

Fire 前端使用自定义 Hooks 封装复杂业务逻辑和状态管理。

Trading Hooks

useStrategyMetadata

策略元数据管理 Hook。

功能

返回接口

interface UseStrategyMetadataReturn {
  strategies: StrategyMetadata[];                    // 所有策略列表
  strategyMap: Map<string, StrategyMetadata>;        // 策略 ID -> 元数据映射
  parametersMap: Map<string, ParameterDefinition[]>; // 策略 ID -> 参数定义映射
  isLoading: boolean;                                // 加载状态
  error: string | null;                              // 错误信息
  refetch: () => Promise<void>;                      // 重新获取
  getStrategiesByCategory: (category: string) => StrategyMetadata[];
  searchStrategies: (query: string) => StrategyMetadata[];
  getStrategyParameters: (strategyId: string) => ParameterDefinition[];
}

使用示例

const {
  strategies,
  strategyMap,
  getStrategiesByCategory,
  searchStrategies
} = useStrategyMetadata();

// 按分类获取策略
const momentumStrategies = getStrategiesByCategory('Momentum');

// 搜索策略
const results = searchStrategies('MACD');

// 获取策略元数据
const macdStrategy = strategyMap.get('macd');

useFlowEditor

单个通道的 Flow 编辑器状态管理 Hook。

功能

核心方法

interface UseFlowEditorReturn {
  // 状态
  nodes: FlowNode[];
  edges: FlowEdge[];
  selectedNode: FlowNode | null;
  isDirty: boolean;
  validationErrors: ValidationError[];
  nodeSelectorExpanded: boolean;       // 节点选择器面板展开状态
  nextColorIndex: number;              // 下一个策略组颜色索引

  // 节点操作
  addStrategy: (strategyId: string, position: { x: number; y: number }) => void;
  removeStrategy: (nodeId: string) => void;
  selectNode: (nodeId: string) => void;
  deselectNode: () => void;

  // 策略组操作 (UX Upgrade 新增)
  addStrategyGroup: (position: { x: number; y: number }) => void;
  removeStrategyGroup: (groupId: string) => void;
  updateGroupWeight: (groupId: string, weight: number) => void;
  updateGroupName: (groupId: string, name: string) => void;
  addStrategyToGroup: (groupId: string, strategyId: string) => void;
  removeStrategyFromGroup: (groupId: string, strategyId: string) => void;

  // 参数更新
  updateStrategyWeight: (nodeId: string, weight: number) => void;
  updateStrategyParameters: (nodeId: string, parameters: Record<string, any>) => void;

  // 面板操作
  toggleNodeSelector: () => void;
  setNodeSelectorExpanded: (expanded: boolean) => void;

  // 布局
  applyAutoLayout: () => void;

  // 配置转换
  loadFromConfig: (config: ChannelConfig) => void;
  exportToConfig: () => ChannelConfig;

  // 验证
  validate: () => boolean;
  validateAllNodes: () => string[];
  clearErrors: () => void;
}

使用示例

const {
  nodes,
  edges,
  addStrategy,
  addStrategyGroup,
  updateStrategyWeight,
  validate,
  exportToConfig
} = useFlowEditor({ channelState: initialState });

// 添加策略组
addStrategyGroup({ x: 100, y: 100 });

// 添加策略到组
addStrategyToGroup('group-1', 'momentum_breakout');

// 添加独立策略
addStrategy('macd', { x: 400, y: 100 });

// 更新权重
updateStrategyWeight('node-1', 0.6);

// 验证并导出
if (validate()) {
  const config = exportToConfig();
  saveConfig(config);
}

useChannelConfig

多通道配置管理 Hook(支持最多 3 个通道)。

功能

核心方法

interface UseChannelConfigReturn {
  // 状态
  channels: ChannelFlowState[];
  activeChannelIndex: number;
  totalCapitalAllocation: number;

  // 通道操作
  addChannel: (channelType?: ChannelType) => void;          // 最多 3 个
  removeChannel: (index: number) => void;                    // 最少 1 个
  setActiveChannel: (index: number) => void;
  toggleChannel: (index: number) => void;

  // 资金管理
  updateCapitalAllocation: (index: number, allocation: number) => void;
  autoBalanceCapital: () => void;                           // 自动平衡至总和 = 1.0

  // 批量操作
  setChannels: (channels: ChannelFlowState[]) => void;     // 用于加载预设

  // 验证
  isValidAllocation: () => boolean;
}

使用示例

const {
  channels,
  addChannel,
  updateCapitalAllocation,
  autoBalanceCapital,
  isValidAllocation
} = useChannelConfig({ maxChannels: 3 });

// 添加通道
addChannel('aggressive');

// 手动调整资金分配
updateCapitalAllocation(0, 0.5);
updateCapitalAllocation(1, 0.3);
updateCapitalAllocation(2, 0.2);

// 或自动平衡
autoBalanceCapital(); // 均分为 0.333, 0.333, 0.334

useSaveConfig

配置保存逻辑 Hook(支持覆盖/另存为)。

功能

保存模式

type SaveMode = 'new' | 'save_as' | 'overwrite';

// new - 无源预设,保存为新配置
// save_as - 有源预设但已修改,默认另存为
// overwrite - 有源预设且已修改,可覆盖

使用示例

const {
  hasChanges,
  suggestedSaveMode,
  defaultSaveAsName,
  compareConfigs
} = useSaveConfig({
  currentConfig,
  originalConfig,
  sourcePresetName: 'Aggressive Preset'
});

if (hasChanges) {
  if (suggestedSaveMode === 'save_as') {
    const newName = defaultSaveAsName; // "Aggressive Preset (Modified)"
    saveAsNewTemplate(newName, currentConfig);
  } else if (suggestedSaveMode === 'overwrite') {
    confirmOverwrite().then(() => {
      saveTemplate(currentConfig);
    });
  }
}

useCustomTemplates

自定义模板 CRUD 操作 Hook。

功能

返回接口

interface UseCustomTemplatesReturn {
  templates: CustomTemplate[];
  isLoading: boolean;
  error: string | null;

  loadTemplates: () => Promise<void>;
  saveAsTemplate: (name: string, description: string, config: ChannelConfig[]) => Promise<CustomTemplate>;
  renameTemplate: (id: string, newName: string) => Promise<void>;
  removeTemplate: (id: string) => Promise<void>;
  getTemplateById: (id: string) => CustomTemplate | undefined;
}

使用示例

const {
  templates,
  saveAsTemplate,
  renameTemplate,
  removeTemplate
} = useCustomTemplates();

// 保存新模板
await saveAsTemplate(
  'My Aggressive Strategy',
  '3 channels with momentum focus',
  channelsConfig
);

// 重命名模板
await renameTemplate(templateId, 'Updated Name');

// 删除模板
await removeTemplate(templateId);

策略管理模块

Fire 的策略管理模块 (/strategies/*) 提供独立的策略配置管理功能,将策略配置从交易模块中分离出来。

模块结构

frontend/src/pages/strategies/
├── management/                    # 策略管理
│   ├── index.tsx                  # 策略列表页(卡片布局)
│   ├── index.module.scss
│   ├── edit.tsx                   # 策略编辑页(Flow Editor)
│   └── edit.module.scss
└── analysis/                      # 技术指标
    ├── index.tsx                  # 指标列表页(表格布局)
    ├── index.module.scss
    ├── detail.tsx                 # 指标详情页
    └── detail.module.scss

策略管理页面 (/strategies/management)

策略列表页 (index.tsx):

策略编辑页 (edit.tsx):

技术指标模块 (/strategies/analysis)

指标列表页 (index.tsx):

指标详情页 (detail.tsx):

交易模块优化

交易启动页 (/trading/*/start.tsx) 现在使用策略选择器而非嵌入式 Flow Editor:

StrategySelector 组件:

会话创建变化

工具函数库

Fire 前端使用工具函数封装常用逻辑,提高代码复用性。

Flow 相关工具

flowSerializer

Flow 图与 JSON 配置的双向转换工具。

核心方法

serializeChannelConfig(nodes, edges) - Flow 图 → JSON

function serializeChannelConfig(
  nodes: FlowNode[],
  edges: FlowEdge[]
): ChannelConfig | null {
  // 1. 提取连接到输出节点的策略
  // 2. 验证权重总和(必须 = 1.0)
  // 3. 构建 ChannelConfig 对象
}

deserializeChannelConfig(config) - JSON → Flow 图

function deserializeChannelConfig(
  config: ChannelConfig
): { nodes: FlowNode[]; edges: FlowEdge[] } {
  // 1. 创建策略节点(3 列网格布局)
  // 2. 创建输出节点(底部居中)
  // 3. 创建连接边
}

布局算法

使用示例

// JSON → Flow
const { nodes, edges } = deserializeChannelConfig(channelConfig);
setFlowState({ nodes, edges });

// Flow → JSON
const config = serializeChannelConfig(nodes, edges);
if (config) {
  saveConfig(config);
}

configValidator

客户端配置验证工具(与后端验证对应)。

核心方法

validateChannelFlowState(channel) - 验证单通道 Flow 状态

function validateChannelFlowState(
  channel: ChannelFlowState
): ValidationError[] {
  const errors: ValidationError[] = [];

  // 1. 检查输出节点存在性
  // 2. 检查策略连接性(断开的策略节点)
  // 3. 验证权重总和(允许 0.0001 误差)
  // 4. 验证参数(必填、范围)

  return errors;
}

validateCapitalAllocation(channels) - 验证资金分配

function validateCapitalAllocation(
  channels: ChannelFlowState[]
): ValidationError[] {
  const errors: ValidationError[] = [];

  // 1. 检查单个通道分配范围(0-1)
  // 2. 验证总分配 = 1.0

  return errors;
}

错误类型

type ValidationErrorType =
  | 'required'        // 缺少必填字段
  | 'out_of_range'    // 超出范围
  | 'invalid_sum'     // 总和无效
  | 'missing'         // 缺少组件
  | 'disconnected'    // 节点未连接
  | 'invalid';        // 无效值

使用示例

const errors = validateChannelFlowState(channel);

if (errors.length > 0) {
  errors.forEach(error => {
    console.error(`${error.field}: ${error.message}`);
  });
}

flowLayoutHelper

Flow 图自动布局算法工具。

核心方法

applyGridLayout(nodes) - 应用网格布局

function applyGridLayout(
  nodes: FlowNode[],
  options?: {
    columns?: number;      // 列数(默认 3)
    hSpacing?: number;     // 水平间距(默认 40px)
    vSpacing?: number;     // 垂直间距(默认 40px)
    startX?: number;       // 起始 X 坐标
    startY?: number;       // 起始 Y 坐标
  }
): FlowNode[] {
  // 按网格排列策略节点
  // 输出节点放置在底部居中
}

使用示例

const layoutedNodes = applyGridLayout(nodes, {
  columns: 3,
  hSpacing: 50,
  vSpacing: 60
});

setNodes(layoutedNodes);

配置

环境配置

// vite.config.ts 环境变量
interface ImportMetaEnv {
  VITE_API_BASE_URL: string;     // API基础地址
  VITE_WS_BASE_URL: string;       // WebSocket地址
  VITE_APP_TITLE: string;         // 应用标题
  VITE_ENABLE_MOCK: string;       // 启用Mock数据
}

主题配置

// Semi Design 主题定制
const customTheme = {
  '--semi-color-primary': '#1890ff',
  '--semi-color-success': '#52c41a',
  '--semi-color-warning': '#faad14',
  '--semi-color-danger': '#f5222d',
};

路由配置

// 路由权限配置
const routeConfig = {
  '/admin/*': { requireAdmin: true },
  '/trading/*': { requireAuth: true },
  '/public/*': { requireAuth: false },
};

相关文档