mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-10 06:20:58 +08:00
## 功能描述 在创建和编辑 Trader 时,支持配置 AI 扫描决策间隔(scan_interval_minutes),允许用户自定义 AI 决策的频率。 ## 修改内容 ### 后端修改 (api/server.go) 1. **CreateTraderRequest** 添加 `ScanIntervalMinutes` 字段 2. **UpdateTraderRequest** 添加 `ScanIntervalMinutes` 字段和 `SystemPromptTemplate` 字段 3. **handleCreateTrader** 处理扫描间隔默认值(默认 3 分钟) 4. **handleUpdateTrader** 支持更新扫描间隔 5. **handleGetTraderConfig** 返回中添加 `scan_interval_minutes` 字段 ### 前端修改 #### web/src/types.ts - `CreateTraderRequest` 添加 `scan_interval_minutes?` 可选字段 - `TraderConfigData` 添加 `scan_interval_minutes` 必填字段 #### web/src/components/TraderConfigModal.tsx - 本地 `TraderConfigData` 接口添加 `scan_interval_minutes` - 初始状态设置默认值为 3 分钟 - 添加 UI 输入框(范围 1-60 分钟) - Label 优化为 "AI 扫描决策间隔 (分钟)" #### web/src/components/AITradersPage.tsx - `handleSaveEditTrader` 的更新请求中添加 `scan_interval_minutes` #### web/src/components/landing/CommunitySection.tsx - 修复 TypeScript 编译错误:定义 `CardProps` 接口 - 修正 `TestimonialCard` 组件的 prop 名称(author → authorName) ## 功能特性 - ✅ 支持 1-60 分钟的自定义间隔 - ✅ 默认值为 3 分钟 - ✅ UI 提示建议范围:3-10 分钟 - ✅ 创建和编辑时均支持配置 - ✅ 后端验证和处理默认值 ## 测试步骤 1. 创建新 Trader,设置自定义扫描间隔(如 10 分钟) 2. 验证 Trader 创建成功 3. 编辑现有 Trader,修改扫描间隔 4. 验证修改保存成功 5. 确认 AI 决策按照新的间隔执行
93 lines
3.3 KiB
TypeScript
93 lines
3.3 KiB
TypeScript
import { motion } from 'framer-motion'
|
||
import AnimatedSection from './AnimatedSection'
|
||
|
||
interface CardProps {
|
||
quote: string;
|
||
authorName: string;
|
||
handle: string;
|
||
avatarUrl: string;
|
||
tweetUrl: string;
|
||
delay: number;
|
||
}
|
||
|
||
function TestimonialCard({ quote, authorName, delay }: CardProps) {
|
||
return (
|
||
<motion.div
|
||
className='p-6 rounded-xl'
|
||
style={{ background: 'var(--brand-dark-gray)', border: '1px solid rgba(240, 185, 11, 0.1)' }}
|
||
initial={{ opacity: 0, y: 20 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
viewport={{ once: true }}
|
||
transition={{ delay }}
|
||
whileHover={{ scale: 1.05 }}
|
||
>
|
||
<p className='text-lg mb-4' style={{ color: 'var(--brand-light-gray)' }}>
|
||
"{quote}"
|
||
</p>
|
||
<div className='flex items-center gap-2'>
|
||
<div className='w-8 h-8 rounded-full' style={{ background: 'var(--binance-yellow)' }} />
|
||
<span className='text-sm font-semibold' style={{ color: 'var(--text-secondary)' }}>
|
||
{authorName}
|
||
</span>
|
||
</div>
|
||
</motion.div>
|
||
)
|
||
}
|
||
|
||
export default function CommunitySection() {
|
||
const staggerContainer = { animate: { transition: { staggerChildren: 0.1 } } }
|
||
|
||
// 推特内容整合(保持原三列布局,超出自动换行)
|
||
const items: CardProps[] = [
|
||
{
|
||
quote:
|
||
'前不久非常火的 AI 量化交易系统 NOF1,在 GitHub 上有人将其复刻并开源,这就是 NOFX 项目。基于 DeepSeek、Qwen 等大语言模型,打造的通用架构 AI 交易操作系统,完成了从决策、到交易、再到复盘的闭环。GitHub: https://github.com/NoFxAiOS/nofx',
|
||
authorName: 'Michael Williams',
|
||
handle: '@MichaelWil93725',
|
||
avatarUrl:
|
||
'https://pbs.twimg.com/profile_images/1767615411594694659/Mj8Fdt6o_400x400.jpg',
|
||
tweetUrl:
|
||
'https://twitter.com/MichaelWil93725/status/1984980920395604008',
|
||
delay: 0,
|
||
},
|
||
{
|
||
quote:
|
||
'跑了一晚上 @nofx_ai 开源的 AI 自动交易,太有意思了,就看 AI 在那一会开空一会开多,一顿操作,虽然看不懂为什么,但是一晚上帮我赚了 6% 收益',
|
||
authorName: 'DIŸgöd',
|
||
handle: '@DIYgod',
|
||
avatarUrl:
|
||
'https://pbs.twimg.com/profile_images/1628393369029181440/r23HDDJk_400x400.jpg',
|
||
tweetUrl: 'https://twitter.com/DIYgod/status/1984442354515017923',
|
||
delay: 0.1,
|
||
},
|
||
{
|
||
quote:
|
||
'Open-source NOFX revives the legendary Alpha Arena, an AI-powered crypto futures battleground. Built on DeepSeek/Qwen AI, it trades live on Binance, Hyperliquid, and Aster DEX, featuring multi-AI battles and self-learning bots',
|
||
authorName: 'Kai',
|
||
handle: '@hqmank',
|
||
avatarUrl:
|
||
'https://pbs.twimg.com/profile_images/1905441261911506945/4YhLIqUm_400x400.jpg',
|
||
tweetUrl: 'https://twitter.com/hqmank/status/1984227431994290340',
|
||
delay: 0.15,
|
||
},
|
||
]
|
||
|
||
return (
|
||
<AnimatedSection>
|
||
<div className='max-w-7xl mx-auto'>
|
||
<motion.div
|
||
className='grid md:grid-cols-3 gap-6'
|
||
variants={staggerContainer}
|
||
initial='initial'
|
||
whileInView='animate'
|
||
viewport={{ once: true }}
|
||
>
|
||
{items.map((item, idx) => (
|
||
<TestimonialCard key={idx} {...item} />
|
||
))}
|
||
</motion.div>
|
||
</div>
|
||
</AnimatedSection>
|
||
)
|
||
}
|