diff --git a/frontend/src/locales/en/common.json b/frontend/src/locales/en/common.json index 808ef5d..0c14178 100644 --- a/frontend/src/locales/en/common.json +++ b/frontend/src/locales/en/common.json @@ -1279,6 +1279,8 @@ "retryConfirm": "Are you sure you want to retry this backtest task? It will continue from the breakpoint and preserve processed trades.", "deleteConfirm": "Are you sure you want to delete this backtest task?", "stopConfirm": "Are you sure you want to stop this backtest task?", + "createCopyTrading": "Create Copy Trading", + "createCopyTradingSuccess": "Copy trading config created successfully", "noTasks": "No backtest tasks", "noTrades": "No trade records", "fetchTasksFailed": "Failed to fetch task list", diff --git a/frontend/src/locales/zh-CN/common.json b/frontend/src/locales/zh-CN/common.json index a9392f8..9a8e6de 100644 --- a/frontend/src/locales/zh-CN/common.json +++ b/frontend/src/locales/zh-CN/common.json @@ -1279,6 +1279,8 @@ "retryConfirm": "确定重新运行此回测任务吗?将从断点继续执行,保留已处理的交易记录。", "deleteConfirm": "确定删除此回测任务吗?", "stopConfirm": "确定停止此回测任务吗?", + "createCopyTrading": "创建跟单", + "createCopyTradingSuccess": "跟单配置创建成功", "noTasks": "暂无回测任务", "noTrades": "暂无交易记录", "fetchTasksFailed": "获取任务列表失败", diff --git a/frontend/src/locales/zh-TW/common.json b/frontend/src/locales/zh-TW/common.json index a4ffea2..a6127d4 100644 --- a/frontend/src/locales/zh-TW/common.json +++ b/frontend/src/locales/zh-TW/common.json @@ -1279,6 +1279,8 @@ "retryConfirm": "確定重新運行此回測任務嗎?將從斷點繼續執行,保留已處理的交易記錄。", "deleteConfirm": "確定刪除此回測任務嗎?", "stopConfirm": "確定停止此回測任務嗎?", + "createCopyTrading": "創建跟單", + "createCopyTradingSuccess": "跟單配置創建成功", "noTasks": "暫無回測任務", "noTrades": "暫無交易記錄", "fetchTasksFailed": "獲取任務列表失敗", diff --git a/frontend/src/pages/BacktestDetail.tsx b/frontend/src/pages/BacktestDetail.tsx index e0d9a27..572aebf 100644 --- a/frontend/src/pages/BacktestDetail.tsx +++ b/frontend/src/pages/BacktestDetail.tsx @@ -1,13 +1,14 @@ import { useState, useEffect } from 'react' import { useParams, useNavigate } from 'react-router-dom' import { Card, Descriptions, Button, Tag, Space, Table, message, Row, Col, Statistic, Spin } from 'antd' -import { ArrowLeftOutlined, ReloadOutlined, DeleteOutlined, StopOutlined } from '@ant-design/icons' +import { ArrowLeftOutlined, ReloadOutlined, DeleteOutlined, StopOutlined, CopyOutlined } from '@ant-design/icons' import { useTranslation } from 'react-i18next' import { formatUSDC } from '../utils' import { backtestService } from '../services/api' import type { BacktestTaskDto, BacktestConfigDto, BacktestStatisticsDto, BacktestTradeDto } from '../types/backtest' import { useMediaQuery } from 'react-responsive' import BacktestChart from './BacktestChart' +import AddCopyTradingModal from './CopyTradingOrders/AddModal' const BacktestDetail: React.FC = () => { const { t } = useTranslation() @@ -16,7 +17,7 @@ const BacktestDetail: React.FC = () => { const isMobile = useMediaQuery({ maxWidth: 768 }) const [loading, setLoading] = useState(false) const [task, setTask] = useState(null) - const [, setConfig] = useState(null) + const [config, setConfig] = useState(null) const [statistics, setStatistics] = useState(null) const [trades, setTrades] = useState([]) const [allTrades, setAllTrades] = useState([]) // 用于图表显示的所有交易数据 @@ -26,6 +27,10 @@ const BacktestDetail: React.FC = () => { const [tradesSize] = useState(20) const [polling, setPolling] = useState(null) + // 创建跟单配置 Modal + const [addCopyTradingModalVisible, setAddCopyTradingModalVisible] = useState(false) + const [preFilledConfig, setPreFilledConfig] = useState(null) + // 获取回测任务详情 const fetchTaskDetail = async () => { setLoading(true) @@ -173,6 +178,36 @@ const BacktestDetail: React.FC = () => { fetchTrades(tradesPage) } + // 一键创建跟单配置 + const handleCreateCopyTrading = () => { + console.log('[BacktestDetail] handleCreateCopyTrading called, task:', task, 'config:', config) + if (!task || !config) { + console.log('[BacktestDetail] No task or config available') + return + } + + // 预填充回测任务的配置参数(从 config 中获取) + const preFilled = { + leaderId: task.leaderId, + copyMode: config.copyMode, + copyRatio: config.copyMode === 'RATIO' ? parseFloat(config.copyRatio) * 100 : undefined, + fixedAmount: config.copyMode === 'FIXED' ? config.fixedAmount : undefined, + maxOrderSize: parseFloat(config.maxOrderSize), + minOrderSize: parseFloat(config.minOrderSize), + maxDailyLoss: parseFloat(config.maxDailyLoss), + maxDailyOrders: config.maxDailyOrders, + supportSell: config.supportSell, + keywordFilterMode: config.keywordFilterMode || 'DISABLED', + keywords: config.keywords || [], + configName: `回测任务-${task.taskName}` + } + + console.log('[BacktestDetail] Generated preFilled config:', preFilled) + console.log('[BacktestDetail] Setting preFilledConfig and opening modal') + setPreFilledConfig(preFilled) + setAddCopyTradingModalVisible(true) + } + // 状态标签颜色 const getStatusColor = (status: string) => { switch (status) { @@ -285,6 +320,11 @@ const BacktestDetail: React.FC = () => { + {task.status === 'COMPLETED' && ( + + )} {(task.status === 'RUNNING' || task.status === 'PENDING') && ( + {record.status === 'COMPLETED' && ( + + )} {record.status === 'RUNNING' && (