From f2b04707f7349b04b95eaf7317191f4f17954407 Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Sat, 1 Nov 2025 10:30:24 +0800 Subject: [PATCH 01/12] Update README.md --- README.md | 146 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 04073116..cdce875e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,46 @@ -# 🤖 NOFX - AI-Driven Crypto Futures Auto Trading Competition System +# 🤖 NOFX - Agentic Trading OS [![Go Version](https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat&logo=go)](https://golang.org/) [![React](https://img.shields.io/badge/React-18+-61DAFB?style=flat&logo=react)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat&logo=typescript)](https://www.typescriptlang.org/) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) +[![Backed by Amber.ac](https://img.shields.io/badge/Backed%20by-Amber.ac-orange.svg)](https://amber.ac) **Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) --- -An automated crypto futures trading system powered by **DeepSeek/Qwen AI**, supporting **Binance, Hyperliquid, and Aster DEX exchanges**, **multi-AI model live trading competition**, featuring comprehensive market analysis, AI decision-making, **self-learning mechanism**, and professional Web monitoring interface. +## 🚀 Universal AI Trading Operating System + +**NOFX** is a **universal Agentic Trading OS** built on a unified architecture. We've successfully closed the loop in crypto markets: **"Multi-Agent Decision → Unified Risk Control → Low-Latency Execution → Live/Paper Account Backtesting"**, and are now expanding this same technology stack to **stocks, futures, options, forex, and all financial markets**. + +### 🎯 Core Features + +- **Universal Data & Backtesting Layer**: Cross-market, cross-timeframe, cross-exchange unified representation and factor library, accumulating transferable "strategy memory" +- **Multi-Agent Self-Play & Self-Evolution**: Strategies automatically compete and select the best, continuously iterating based on account-level PnL and risk constraints +- **Integrated Execution & Risk Control**: Low-latency routing, slippage/risk control sandbox, account-level limits, one-click market switching + +### 🏢 Backed by [Amber.ac](https://amber.ac) + +### 👥 Core Team + +- **Tinkle** - Technology & Developer Relations + - Leading all technical development and architecture + - Building the developer community + - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) + +- **Zack** - Market & Fundraising + - Leading market strategy and business development + - Managing fundraising and investor relations + - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) + +### 💼 Seed Funding Round Open + +We are currently raising our **seed round**. + +**For investment inquiries, please contact Zack** via Twitter DM. + +--- > ⚠️ **Risk Warning**: This system is experimental. AI auto-trading carries significant risks. Strongly recommended for learning/research purposes or testing with small amounts only! @@ -90,58 +121,64 @@ A Binance-compatible decentralized perpetual futures exchange! --- -## ✨ Core Features +## ✨ Current Implementation - Crypto Markets -### 🏆 Multi-AI Competition Mode -- **Qwen vs DeepSeek** live trading battle -- Independent account management and decision logs -- Real-time performance comparison charts -- ROI PK and win rate statistics +NOFX is currently **fully operational in cryptocurrency markets** with the following proven capabilities: -### 🧠 AI Self-Learning Mechanism (NEW!) -- **Historical Feedback**: Analyzes last 20 cycles of trading performance before each decision -- **Smart Optimization**: - - Identifies best/worst performing coins - - Calculates win rate, profit/loss ratio, average profit - - Avoids repeating mistakes (consecutive losing coins) +### 🏆 Multi-Agent Competition Framework +- **Live Agent Battle**: Qwen vs DeepSeek models compete in real-time trading +- **Independent Account Management**: Each agent maintains its own decision logs and performance metrics +- **Real-time Performance Comparison**: Live ROI tracking, win rate statistics, and head-to-head analysis +- **Self-Evolution Loop**: Agents learn from their historical performance and continuously improve + +### 🧠 AI Self-Learning & Optimization +- **Historical Feedback System**: Analyzes last 20 trading cycles before each decision +- **Smart Performance Analysis**: + - Identifies best/worst performing assets + - Calculates win rate, profit/loss ratio, average profit in real USDT terms + - Avoids repeating mistakes (consecutive losing patterns) - Reinforces successful strategies (high win rate patterns) -- **Dynamic Adjustment**: AI autonomously adjusts trading style based on historical performance +- **Dynamic Strategy Adjustment**: AI autonomously adapts trading style based on backtest results -### 📊 Intelligent Market Analysis -- **3-minute K-line**: Real-time price, EMA20, MACD, RSI(7) -- **4-hour K-line**: Long-term trend, EMA20/50, ATR, RSI(14) -- **Open Interest Analysis**: Market sentiment, capital flow judgment -- **OI Top Tracking**: Top 20 coins with fastest growing open interest -- **AI500 Coin Pool**: Automatic high-score coin screening -- **Liquidity Filter**: Auto-filters low liquidity coins (<15M USD position value) +### 📊 Universal Market Data Layer (Crypto Implementation) +- **Multi-Timeframe Analysis**: 3-minute real-time + 4-hour trend data +- **Technical Indicators**: EMA20/50, MACD, RSI(7/14), ATR +- **Open Interest Tracking**: Market sentiment, capital flow analysis +- **Liquidity Filtering**: Auto-filters low liquidity assets (<15M USD) +- **Cross-Exchange Support**: Binance, Hyperliquid, Aster DEX with unified data interface -### 🎯 Professional Risk Control -- **Per-Coin Position Limit**: - - Altcoins ≤ 1.5x account equity - - BTC/ETH ≤ 10x account equity -- **Configurable Leverage** (v2.0.3+): - - Set maximum leverage in config.json - - Default: 5x for all coins (safe for subaccounts) - - Main accounts can increase: Altcoins up to 20x, BTC/ETH up to 50x - - ⚠️ Binance subaccounts restricted to ≤5x leverage -- **Margin Management**: Total usage ≤90%, AI autonomous decision on usage rate -- **Risk-Reward Ratio**: Mandatory ≥1:2 (stop-loss:take-profit) -- **Prevent Position Stacking**: No duplicate opening of same coin/direction +### 🎯 Unified Risk Control System +- **Position Limits**: Per-asset limits (Altcoins ≤1.5x equity, BTC/ETH ≤10x equity) +- **Configurable Leverage**: Dynamic leverage from 1x to 50x based on asset class and account type +- **Margin Management**: Total usage ≤90%, AI-controlled allocation +- **Risk-Reward Enforcement**: Mandatory ≥1:2 stop-loss to take-profit ratio +- **Anti-Stacking Protection**: Prevents duplicate positions in same asset/direction -### 🎨 Professional UI -- **Professional Trading Interface**: Binance-style visual design -- **Dark Theme**: Classic color scheme (Gold #F0B90B + dark background) -- **Real-time Data**: 5-second refresh for accounts, positions, charts -- **Equity Curve**: Historical account value trend (USD/percentage toggle) -- **Performance Comparison Chart**: Real-time multi-AI ROI comparison -- **Smooth Animations**: Fluid hover, transition, and loading effects +### ⚡ Low-Latency Execution Engine +- **Multi-Exchange API Integration**: Binance Futures, Hyperliquid DEX, Aster DEX +- **Automatic Precision Handling**: Smart order size & price formatting per exchange +- **Priority Execution**: Close existing positions first, then open new ones +- **Slippage Control**: Pre-execution validation, real-time precision checks -### 📝 Complete Decision Recording -- **Chain of Thought**: AI's complete reasoning process (CoT) -- **Historical Performance**: Overall win rate, average profit, profit/loss ratio -- **Recent Trades**: Last 5 trade details (entry price → exit price → P/L%) -- **Coin Statistics**: Per-coin performance (win rate, average P/L) -- **JSON Logs**: Complete decision records for post-trade analysis +### 🎨 Professional Monitoring Interface +- **Binance-Style Dashboard**: Professional dark theme with real-time updates +- **Equity Curves**: Historical account value tracking (USD/percentage toggle) +- **Performance Charts**: Multi-agent ROI comparison with live updates +- **Complete Decision Logs**: Full Chain of Thought (CoT) reasoning for every trade +- **5-Second Data Refresh**: Real-time account, position, and P/L updates + +--- + +## 🔮 Roadmap - Universal Market Expansion + +Our proven crypto infrastructure is being extended to: + +- **📈 Stock Markets**: US equities, A-shares, Hong Kong stocks +- **📊 Futures Markets**: Commodity futures, index futures +- **🎯 Options Trading**: Equity options, crypto options +- **💱 Forex Markets**: Major currency pairs, cross rates + +**Same architecture. Same agent framework. All markets.** --- @@ -1274,10 +1311,23 @@ Issues and Pull Requests are welcome! --- -## 📬 Contact +## 📬 Contact & Business Inquiries +### 💼 Investment & Fundraising +We are currently raising our **seed round**. For investment opportunities: + +- **Contact**: Zack (Market & Fundraising Lead) +- **Twitter/X**: *[To be filled]* + +### 🤝 Business Partnerships & Technical Collaborations +For strategic partnerships and developer collaborations: + +- **Contact**: Tinkle (Technology Lead) - **Twitter/X**: [@Web3Tinkle](https://x.com/Web3Tinkle) + +### 🐛 Technical Support - **GitHub Issues**: [Submit an Issue](https://github.com/tinkle-community/nofx/issues) +- **Developer Community**: [Telegram Group](https://t.me/nofx_dev_community) --- From df4db713062ce10cf387b24ec9d89ad9816caba0 Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Sat, 1 Nov 2025 10:41:37 +0800 Subject: [PATCH 02/12] Update README: Add Zack's Twitter handle and refine team/funding info --- README.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/README.md b/README.md index cdce875e..d7ea672a 100644 --- a/README.md +++ b/README.md @@ -1311,19 +1311,8 @@ Issues and Pull Requests are welcome! --- -## 📬 Contact & Business Inquiries +## 📬 Contact -### 💼 Investment & Fundraising -We are currently raising our **seed round**. For investment opportunities: - -- **Contact**: Zack (Market & Fundraising Lead) -- **Twitter/X**: *[To be filled]* - -### 🤝 Business Partnerships & Technical Collaborations -For strategic partnerships and developer collaborations: - -- **Contact**: Tinkle (Technology Lead) -- **Twitter/X**: [@Web3Tinkle](https://x.com/Web3Tinkle) ### 🐛 Technical Support - **GitHub Issues**: [Submit an Issue](https://github.com/tinkle-community/nofx/issues) From c5b1e9899570dd10345f8c30ffdbcceccae120bb Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Sat, 1 Nov 2025 10:49:48 +0800 Subject: [PATCH 03/12] Update multilingual READMEs: Reposition as Agentic Trading OS with team info --- README.ru.md | 35 ++++++++++++- README.uk.md | 35 ++++++++++++- README.zh-CN.md | 136 +++++++++++++++++++++++++++++++----------------- 3 files changed, 153 insertions(+), 53 deletions(-) diff --git a/README.ru.md b/README.ru.md index 4761e106..d4f6291c 100644 --- a/README.ru.md +++ b/README.ru.md @@ -1,15 +1,46 @@ -# 🤖 NOFX - AI-управляемая система автоматической торговли фьючерсами Binance +# 🤖 NOFX - Agentic Trading OS [![Go Version](https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat&logo=go)](https://golang.org/) [![React](https://img.shields.io/badge/React-18+-61DAFB?style=flat&logo=react)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat&logo=typescript)](https://www.typescriptlang.org/) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) +[![Backed by Amber.ac](https://img.shields.io/badge/Backed%20by-Amber.ac-orange.svg)](https://amber.ac) **Языки / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) --- -Автоматизированная система торговли криптовалютными фьючерсами на базе **DeepSeek/Qwen AI**, поддерживающая **Binance, Hyperliquid и Aster DEX биржи**, **конкуренцию нескольких AI-моделей в реальной торговле**, с полным анализом рынка, принятием решений AI, **механизмом самообучения** и профессиональным веб-интерфейсом мониторинга. +## 🚀 Универсальная AI Торговая Операционная Система + +**NOFX** - это **универсальная Agentic Trading OS**, построенная на единой архитектуре. Мы успешно замкнули цикл на криптовалютных рынках: **"Решение Multi-Agent → Единый Контроль Рисков → Исполнение с Низкой Задержкой → Бэктестинг Реальных/Бумажных Счетов"**, и сейчас расширяем этот же технологический стек на **акции, фьючерсы, опционы, форекс и все финансовые рынки**. + +### 🎯 Основные Возможности + +- **Универсальный Слой Данных и Бэктестинга**: Кросс-рыночное, кросс-таймфреймовое, кросс-биржевое единое представление и библиотека факторов, накапливающая переносимую "память стратегий" +- **Multi-Agent Самоигра и Самоэволюция**: Стратегии автоматически конкурируют и выбирают лучшие, непрерывно итерируясь на основе PnL на уровне счета и ограничений рисков +- **Интегрированное Исполнение и Контроль Рисков**: Маршрутизация с низкой задержкой, песочница проскальзывания/контроля рисков, лимиты на уровне счета, переключение рынков одним кликом + +### 🏢 При поддержке [Amber.ac](https://amber.ac) + +### 👥 Основная Команда + +- **Tinkle** - Технологии и Отношения с Разработчиками + - Руководит всей технической разработкой и архитектурой + - Развивает сообщество разработчиков + - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) + +- **Zack** - Рынок и Привлечение Инвестиций + - Руководит рыночной стратегией и развитием бизнеса + - Управляет привлечением инвестиций и отношениями с инвесторами + - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) + +### 💼 Открыт Посевной Раунд Финансирования + +Мы в настоящее время привлекаем **посевной раунд**. + +**По вопросам инвестиций обращайтесь к Zack** через Twitter DM. + +--- > ⚠️ **Предупреждение о рисках**: Эта система экспериментальная. Автоматическая торговля с AI несет значительные риски. Настоятельно рекомендуется использовать только для обучения/исследований или тестирования с небольшими суммами! diff --git a/README.uk.md b/README.uk.md index 55ef2584..45acd48d 100644 --- a/README.uk.md +++ b/README.uk.md @@ -1,15 +1,46 @@ -# 🤖 NOFX - AI-керована система автоматичної торгівлі ф'ючерсами Binance +# 🤖 NOFX - Agentic Trading OS [![Go Version](https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat&logo=go)](https://golang.org/) [![React](https://img.shields.io/badge/React-18+-61DAFB?style=flat&logo=react)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat&logo=typescript)](https://www.typescriptlang.org/) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) +[![Backed by Amber.ac](https://img.shields.io/badge/Backed%20by-Amber.ac-orange.svg)](https://amber.ac) **Мови / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) --- -Автоматизована система торгівлі криптовалютними ф'ючерсами на базі **DeepSeek/Qwen AI**, що підтримує **Binance, Hyperliquid та Aster DEX біржі**, **змагання кількох AI-моделей у реальній торгівлі**, з повним аналізом ринку, прийняттям рішень AI, **механізмом самонавчання** та професійним веб-інтерфейсом моніторингу. +## 🚀 Універсальна AI Торгова Операційна Система + +**NOFX** - це **універсальна Agentic Trading OS**, побудована на єдиній архітектурі. Ми успішно замкнули цикл на криптовалютних ринках: **"Рішення Multi-Agent → Єдиний Контроль Ризиків → Виконання з Низькою Затримкою → Бектестинг Реальних/Паперових Рахунків"**, і зараз розширюємо цей же технологічний стек на **акції, ф'ючерси, опціони, форекс та всі фінансові ринки**. + +### 🎯 Основні Можливості + +- **Універсальний Шар Даних та Бектестингу**: Крос-ринкове, крос-таймфреймове, крос-біржеве єдине представлення та бібліотека факторів, що накопичує переносиму "пам'ять стратегій" +- **Multi-Agent Самогра та Самоеволюція**: Стратегії автоматично конкурують і вибирають кращі, безперервно ітеруючись на основі PnL на рівні рахунку та обмежень ризиків +- **Інтегроване Виконання та Контроль Ризиків**: Маршрутизація з низькою затримкою, пісочниця прослизання/контролю ризиків, ліміти на рівні рахунку, перемикання ринків одним кліком + +### 🏢 За підтримки [Amber.ac](https://amber.ac) + +### 👥 Основна Команда + +- **Tinkle** - Технології та Відносини з Розробниками + - Керує всією технічною розробкою та архітектурою + - Розвиває спільноту розробників + - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) + +- **Zack** - Ринок та Залучення Інвестицій + - Керує ринковою стратегією та розвитком бізнесу + - Управляє залученням інвестицій та відносинами з інвесторами + - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) + +### 💼 Відкритий Посівний Раунд Фінансування + +Ми зараз залучаємо **посівний раунд**. + +**З питань інвестицій звертайтесь до Zack** через Twitter DM. + +--- > ⚠️ **Попередження про ризики**: Ця система експериментальна. Автоматична торгівля з AI несе значні ризики. Наполегливо рекомендується використовувати лише для навчання/досліджень або тестування з невеликими сумами! diff --git a/README.zh-CN.md b/README.zh-CN.md index dbdb2df9..fd71f0d9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,15 +1,46 @@ -# 🤖 NOFX - AI驱动的币安合约自动交易竞赛系统 +# 🤖 NOFX - AI交易操作系统 [![Go Version](https://img.shields.io/badge/Go-1.21+-00ADD8?style=flat&logo=go)](https://golang.org/) [![React](https://img.shields.io/badge/React-18+-61DAFB?style=flat&logo=react)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=flat&logo=typescript)](https://www.typescriptlang.org/) [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) +[![Backed by Amber.ac](https://img.shields.io/badge/Backed%20by-Amber.ac-orange.svg)](https://amber.ac) **语言 / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) --- -一个基于 **DeepSeek/Qwen AI** 的加密货币期货自动交易系统,支持 **Binance、Hyperliquid和Aster DEX交易所**,**多AI模型实盘竞赛**,具备完整的市场分析、AI决策、**自我学习机制**和专业的Web监控界面。 +## 🚀 通用AI交易操作系统 + +**NOFX** 是通用架构的 **AI交易操作系统(Agentic Trading OS)**。我们已在加密市场打通"**多智能体决策 → 统一风控 → 低延迟执行 → 真实/纸面账户复盘**"的闭环,正按同一技术栈扩展到**股票、期货、期权、外汇等所有市场**。 + +### 🎯 核心特性 + +- **通用数据与回测层**:跨市场、跨周期、跨交易所统一表示与因子库,沉淀可迁移的"策略记忆" +- **多智能体自博弈与自进化**:策略自动对战择优,按账户级 PnL 与风险约束持续迭代 +- **执行与风控一体化**:低延迟路由、滑点/风控沙箱、账户级限额,一键切换市场 + +### 🏢 由 [Amber.ac](https://amber.ac) 背书 + +### 👥 核心团队 + +- **Tinkle** - 技术与开发者关系负责人 + - 负责所有技术开发和架构设计 + - 建设开发者社区 + - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) + +- **Zack** - 市场与融资负责人 + - 负责市场战略和业务拓展 + - 管理融资和投资者关系 + - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) + +### 💼 种子轮融资进行中 + +我们正在进行**种子轮融资**。 + +**投资咨询请联系 Zack**,通过 Twitter 私信。 + +--- > ⚠️ **风险提示**:本系统为实验性项目,AI自动交易存在重大风险,强烈建议仅用于学习研究或小额资金测试! @@ -90,58 +121,64 @@ NOFX现已支持**三大交易所**:Binance、Hyperliquid和Aster DEX! --- -## ✨ 核心特性 +## ✨ 当前实现 - 加密货币市场 -### 🏆 多AI竞赛模式 -- **Qwen vs DeepSeek** 实盘对抗 -- 独立账户管理,独立决策日志 -- 实时性能对比图表 -- 收益率PK,胜率统计 +NOFX 目前已在**加密货币市场全面运行**,具备以下经过验证的能力: -### 🧠 AI自我学习机制(NEW!) -- **历史反馈**: 每次决策前分析最近20个周期的交易表现 -- **智能优化**: - - 识别表现最佳/最差币种 - - 计算胜率、盈亏比、平均盈利 - - 避免重复错误(连续亏损的币种) - - 强化成功策略(高胜率的交易模式) -- **动态调整**: AI根据历史表现自主调整交易风格 +### 🏆 多智能体竞赛框架 +- **实时智能体对战**:Qwen vs DeepSeek 模型实时交易竞赛 +- **独立账户管理**:每个智能体维护独立的决策日志和性能指标 +- **实时性能对比**:实时 ROI 追踪、胜率统计、正面对抗分析 +- **自进化循环**:智能体从历史表现中学习,持续改进 -### 📊 智能市场分析 -- **3分钟K线**: 实时价格、EMA20、MACD、RSI(7) -- **4小时K线**: 长期趋势、EMA20/50、ATR、RSI(14) -- **持仓量分析**: 市场情绪、资金流向判断 -- **OI Top追踪**: 持仓量增长最快的20个币种 -- **AI500币种池**: 高评分币种自动筛选 -- **流动性过滤**: 自动过滤持仓价值<15M USD的低流动性币种 +### 🧠 AI 自学习与优化 +- **历史反馈系统**:每次决策前分析最近 20 个交易周期 +- **智能性能分析**: + - 识别表现最佳/最差资产 + - 计算胜率、盈亏比、以真实 USDT 计的平均盈利 + - 避免重复错误(连续亏损模式) + - 强化成功策略(高胜率模式) +- **动态策略调整**:AI 根据回测结果自主调整交易风格 -### 🎯 专业风险控制 -- **单币种仓位上限**: - - 山寨币 ≤ 1.5倍账户净值 - - BTC/ETH ≤ 10倍账户净值 -- **可配置杠杆** (v2.0.3+): - - 在config.json中设置最大杠杆 - - 默认:所有币种5倍(子账户安全) - - 主账户可增加:山寨币最高20倍,BTC/ETH最高50倍 - - ⚠️ 币安子账户限制≤5倍杠杆 -- **保证金管理**: 总使用率≤90%,AI自主决策使用率 -- **风险回报比**: 强制≥1:2(止损:止盈) -- **防止仓位叠加**: 同币种同方向不允许重复开仓 +### 📊 通用市场数据层(加密货币实现) +- **多时间框架分析**:3分钟实时 + 4小时趋势数据 +- **技术指标**:EMA20/50、MACD、RSI(7/14)、ATR +- **持仓量追踪**:市场情绪、资金流向分析 +- **流动性过滤**:自动过滤低流动性资产(<15M USD) +- **跨交易所支持**:Binance、Hyperliquid、Aster DEX,统一数据接口 -### 🎨 风格UI -- **专业交易界面**: 视觉设计 -- **暗色主题**: 经典配色(金色#F0B90B + 深色背景) -- **实时数据**: 5秒刷新账户、持仓、图表 -- **收益率曲线**: 账户净值历史走势(美元/百分比切换) -- **性能对比图**: 多AI收益率实时对比 -- **动画效果**: 流畅的hover、过渡、加载动画 +### 🎯 统一风控系统 +- **仓位限制**:单资产限制(山寨币≤1.5x净值,BTC/ETH≤10x净值) +- **可配置杠杆**:根据资产类别和账户类型动态调整 1x 到 50x +- **保证金管理**:总使用率≤90%,AI 控制分配 +- **风险回报强制执行**:强制≥1:2 的止损止盈比 +- **防叠加保护**:防止同一资产/方向的重复仓位 -### 📝 完整决策记录 -- **思维链记录**: AI的完整推理过程(CoT) -- **历史表现**: 整体胜率、平均盈利、盈亏比 -- **最近交易**: 最近5笔交易详情(开仓价→平仓价→盈亏%) -- **币种统计**: 各币种表现(胜率、平均盈亏) -- **JSON日志**: 每次决策完整记录,便于复盘分析 +### ⚡ 低延迟执行引擎 +- **多交易所 API 集成**:Binance Futures、Hyperliquid DEX、Aster DEX +- **自动精度处理**:每个交易所智能订单大小和价格格式化 +- **优先级执行**:先平仓现有持仓,再开新仓 +- **滑点控制**:执行前验证,实时精度检查 + +### 🎨 专业监控界面 +- **币安风格仪表板**:专业暗色主题,实时更新 +- **净值曲线**:历史账户价值追踪(USD/百分比切换) +- **性能图表**:多智能体 ROI 对比,实时更新 +- **完整决策日志**:每笔交易的完整思维链(CoT)推理 +- **5秒数据刷新**:实时账户、持仓和盈亏更新 + +--- + +## 🔮 路线图 - 通用市场扩展 + +我们经过验证的加密货币基础设施正在扩展到: + +- **📈 股票市场**:美股、A股、港股 +- **📊 期货市场**:商品期货、指数期货 +- **🎯 期权交易**:股票期权、加密期权 +- **💱 外汇市场**:主要货币对、交叉盘 + +**相同架构。相同智能体框架。所有市场。** --- @@ -1306,8 +1343,9 @@ MIT License - 详见 [LICENSE](LICENSE) 文件 ## 📬 联系方式 -- **Twitter/X**: [@Web3Tinkle](https://x.com/Web3Tinkle) +### 🐛 技术支持 - **GitHub Issues**: [提交Issue](https://github.com/tinkle-community/nofx/issues) +- **开发者社区**: [Telegram群组](https://t.me/nofx_dev_community) --- From 736d45577164fda3c5f0bebe29d7477bf0710fa6 Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Sat, 1 Nov 2025 10:53:58 +0800 Subject: [PATCH 04/12] Add official Twitter account @nofx_ai to all READMEs --- README.md | 2 ++ README.ru.md | 2 ++ README.uk.md | 2 ++ README.zh-CN.md | 2 ++ 4 files changed, 8 insertions(+) diff --git a/README.md b/README.md index d7ea672a..b9d3d90b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,8 @@ **Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) +**Official Twitter:** [@nofx_ai](https://x.com/nofx_ai) + --- ## 🚀 Universal AI Trading Operating System diff --git a/README.ru.md b/README.ru.md index d4f6291c..64e544b9 100644 --- a/README.ru.md +++ b/README.ru.md @@ -8,6 +8,8 @@ **Языки / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) +**Официальный Twitter:** [@nofx_ai](https://x.com/nofx_ai) + --- ## 🚀 Универсальная AI Торговая Операционная Система diff --git a/README.uk.md b/README.uk.md index 45acd48d..757fbc82 100644 --- a/README.uk.md +++ b/README.uk.md @@ -8,6 +8,8 @@ **Мови / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) +**Офіційний Twitter:** [@nofx_ai](https://x.com/nofx_ai) + --- ## 🚀 Універсальна AI Торгова Операційна Система diff --git a/README.zh-CN.md b/README.zh-CN.md index fd71f0d9..8fe1a37a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -8,6 +8,8 @@ **语言 / Languages:** [English](README.md) | [中文](README.zh-CN.md) | [Українська](README.uk.md) | [Русский](README.ru.md) +**官方推特:** [@nofx_ai](https://x.com/nofx_ai) + --- ## 🚀 通用AI交易操作系统 From 5adb171bc7595af7778103ed5a760cbb963b9b53 Mon Sep 17 00:00:00 2001 From: nobody <878822589@qq.com> Date: Sat, 1 Nov 2025 11:28:11 +0800 Subject: [PATCH 05/12] Simplify team intro and clarify contact channels - Remove job descriptions, keep only names and Twitter handles - Investment: DM Tinkle or Zack - Partnerships: DM official Twitter @nofx_ai --- README.md | 15 +++++---------- README.ru.md | 15 +++++---------- README.uk.md | 15 +++++---------- README.zh-CN.md | 15 +++++---------- 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index b9d3d90b..05b209e4 100644 --- a/README.md +++ b/README.md @@ -26,21 +26,16 @@ ### 👥 Core Team -- **Tinkle** - Technology & Developer Relations - - Leading all technical development and architecture - - Building the developer community - - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) - -- **Zack** - Market & Fundraising - - Leading market strategy and business development - - Managing fundraising and investor relations - - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) +- **Tinkle** - [@Web3Tinkle](https://x.com/Web3Tinkle) +- **Zack** - [@0x_ZackH](https://x.com/0x_ZackH) ### 💼 Seed Funding Round Open We are currently raising our **seed round**. -**For investment inquiries, please contact Zack** via Twitter DM. +**For investment inquiries**, please DM **Tinkle** or **Zack** via Twitter. + +**For partnerships and collaborations**, please DM our official Twitter [@nofx_ai](https://x.com/nofx_ai). --- diff --git a/README.ru.md b/README.ru.md index 64e544b9..7a06c10a 100644 --- a/README.ru.md +++ b/README.ru.md @@ -26,21 +26,16 @@ ### 👥 Основная Команда -- **Tinkle** - Технологии и Отношения с Разработчиками - - Руководит всей технической разработкой и архитектурой - - Развивает сообщество разработчиков - - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) - -- **Zack** - Рынок и Привлечение Инвестиций - - Руководит рыночной стратегией и развитием бизнеса - - Управляет привлечением инвестиций и отношениями с инвесторами - - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) +- **Tinkle** - [@Web3Tinkle](https://x.com/Web3Tinkle) +- **Zack** - [@0x_ZackH](https://x.com/0x_ZackH) ### 💼 Открыт Посевной Раунд Финансирования Мы в настоящее время привлекаем **посевной раунд**. -**По вопросам инвестиций обращайтесь к Zack** через Twitter DM. +**По вопросам инвестиций**, пишите в DM **Tinkle** или **Zack** в Twitter. + +**По вопросам партнерства и сотрудничества**, пишите в DM нашего официального Twitter [@nofx_ai](https://x.com/nofx_ai). --- diff --git a/README.uk.md b/README.uk.md index 757fbc82..a54eef1f 100644 --- a/README.uk.md +++ b/README.uk.md @@ -26,21 +26,16 @@ ### 👥 Основна Команда -- **Tinkle** - Технології та Відносини з Розробниками - - Керує всією технічною розробкою та архітектурою - - Розвиває спільноту розробників - - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) - -- **Zack** - Ринок та Залучення Інвестицій - - Керує ринковою стратегією та розвитком бізнесу - - Управляє залученням інвестицій та відносинами з інвесторами - - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) +- **Tinkle** - [@Web3Tinkle](https://x.com/Web3Tinkle) +- **Zack** - [@0x_ZackH](https://x.com/0x_ZackH) ### 💼 Відкритий Посівний Раунд Фінансування Ми зараз залучаємо **посівний раунд**. -**З питань інвестицій звертайтесь до Zack** через Twitter DM. +**З питань інвестицій**, пишіть в DM **Tinkle** або **Zack** в Twitter. + +**З питань партнерства та співпраці**, пишіть в DM нашого офіційного Twitter [@nofx_ai](https://x.com/nofx_ai). --- diff --git a/README.zh-CN.md b/README.zh-CN.md index 8fe1a37a..1a28811d 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -26,21 +26,16 @@ ### 👥 核心团队 -- **Tinkle** - 技术与开发者关系负责人 - - 负责所有技术开发和架构设计 - - 建设开发者社区 - - Twitter/X: [@Web3Tinkle](https://x.com/Web3Tinkle) - -- **Zack** - 市场与融资负责人 - - 负责市场战略和业务拓展 - - 管理融资和投资者关系 - - Twitter/X: [@0x_ZackH](https://x.com/0x_ZackH) +- **Tinkle** - [@Web3Tinkle](https://x.com/Web3Tinkle) +- **Zack** - [@0x_ZackH](https://x.com/0x_ZackH) ### 💼 种子轮融资进行中 我们正在进行**种子轮融资**。 -**投资咨询请联系 Zack**,通过 Twitter 私信。 +**投资咨询**,请通过 Twitter 私信联系 **Tinkle** 或 **Zack**。 + +**商务合作**,请私信官方推特 [@nofx_ai](https://x.com/nofx_ai)。 --- From 8bc06ae6193bab1e0b811df7152ad9bd8eec8a45 Mon Sep 17 00:00:00 2001 From: tangmengqiu <1124090103@qq.com> Date: Fri, 31 Oct 2025 23:58:44 -0400 Subject: [PATCH 06/12] fix: Complete i18n implementation for English language display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit addresses the issue where switching to English still showed Chinese text in many UI elements. Changes made: - Added 40+ missing translation keys to translations.ts for both English and Chinese - Updated App.tsx to use t() function for all hardcoded text (logout button, loading message) - Updated AITradersPage.tsx extensively: - Replaced all alert/confirm messages with translation keys - Updated status labels (inUse, enabled, configured) - Updated all modal components (SignalSource, ModelConfig, ExchangeConfig) - Added language prop to all modal components - Replaced all Chinese UI text with translation function calls The implementation now properly supports language switching between English and Chinese throughout the entire application. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- web/src/App.tsx | 4 +- web/src/components/AITradersPage.tsx | 167 ++++++++++++++------------- web/src/i18n/translations.ts | 122 +++++++++++++++++++ 3 files changed, 212 insertions(+), 81 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index 228c87ef..c6092b5d 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -179,7 +179,7 @@ function App() { style={{ background: 'linear-gradient(135deg, #F0B90B 0%, #FCD535 100%)' }}> ⚡ -

加载中...

+

{t('loading', language)}

); @@ -299,7 +299,7 @@ function App() { className="px-3 py-2 rounded text-sm font-semibold transition-all hover:scale-105" style={{ background: 'rgba(246, 70, 93, 0.1)', color: '#F6465D', border: '1px solid rgba(246, 70, 93, 0.2)' }} > - 退出 + {t('logout', language)} )} diff --git a/web/src/components/AITradersPage.tsx b/web/src/components/AITradersPage.tsx index bc2516cf..9c3da522 100644 --- a/web/src/components/AITradersPage.tsx +++ b/web/src/components/AITradersPage.tsx @@ -3,7 +3,7 @@ import useSWR from 'swr'; import { api } from '../lib/api'; import type { TraderInfo, CreateTraderRequest, AIModel, Exchange } from '../types'; import { useLanguage } from '../contexts/LanguageContext'; -import { t } from '../i18n/translations'; +import { t, type Language } from '../i18n/translations'; import { getExchangeIcon } from './ExchangeIcons'; import { getModelIcon } from './ModelIcons'; import { TraderConfigModal } from './TraderConfigModal'; @@ -149,7 +149,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to create trader:', error); - alert('创建交易员失败'); + alert(t('createTraderFailed', language)); } }; @@ -160,7 +160,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setShowEditModal(true); } catch (error) { console.error('Failed to fetch trader config:', error); - alert('获取交易员配置失败'); + alert(t('getTraderConfigFailed', language)); } }; @@ -170,14 +170,14 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { try { const model = enabledModels?.find(m => m.id === data.ai_model_id); const exchange = enabledExchanges?.find(e => e.id === data.exchange_id); - + if (!model) { - alert('AI模型配置不存在或未启用'); + alert(t('modelConfigNotExist', language)); return; } - + if (!exchange) { - alert('交易所配置不存在或未启用'); + alert(t('exchangeConfigNotExist', language)); return; } @@ -202,19 +202,19 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to update trader:', error); - alert('更新交易员失败'); + alert(t('updateTraderFailed', language)); } }; const handleDeleteTrader = async (traderId: string) => { if (!confirm(t('confirmDeleteTrader', language))) return; - + try { await api.deleteTrader(traderId); mutateTraders(); } catch (error) { console.error('Failed to delete trader:', error); - alert('删除交易员失败'); + alert(t('deleteTraderFailed', language)); } }; @@ -228,7 +228,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { mutateTraders(); } catch (error) { console.error('Failed to toggle trader:', error); - alert('操作失败'); + alert(t('operationFailed', language)); } }; @@ -247,7 +247,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { }; const handleDeleteModelConfig = async (modelId: string) => { - if (!confirm('确定要删除此AI模型配置吗?')) return; + if (!confirm(t('confirmDeleteModel', language))) return; try { const updatedModels = allModels?.map(m => @@ -272,7 +272,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingModel(null); } catch (error) { console.error('Failed to delete model config:', error); - alert('删除配置失败'); + alert(t('deleteConfigFailed', language)); } }; @@ -281,7 +281,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { // 找到要配置的模型(从supportedModels中) const modelToUpdate = supportedModels?.find(m => m.id === modelId); if (!modelToUpdate) { - alert('模型不存在'); + alert(t('modelNotExist', language)); return; } @@ -323,12 +323,12 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingModel(null); } catch (error) { console.error('Failed to save model config:', error); - alert('保存配置失败'); + alert(t('saveConfigFailed', language)); } }; const handleDeleteExchangeConfig = async (exchangeId: string) => { - if (!confirm('确定要删除此交易所配置吗?')) return; + if (!confirm(t('confirmDeleteExchange', language))) return; try { const updatedExchanges = allExchanges?.map(e => @@ -355,7 +355,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingExchange(null); } catch (error) { console.error('Failed to delete exchange config:', error); - alert('删除交易所配置失败'); + alert(t('deleteExchangeConfigFailed', language)); } }; @@ -364,7 +364,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { // 找到要配置的交易所(从supportedExchanges中) const exchangeToUpdate = supportedExchanges?.find(e => e.id === exchangeId); if (!exchangeToUpdate) { - alert('交易所不存在'); + alert(t('exchangeNotExist', language)); return; } @@ -411,7 +411,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setEditingExchange(null); } catch (error) { console.error('Failed to save exchange config:', error); - alert('保存交易所配置失败'); + alert(t('saveConfigFailed', language)); } }; @@ -432,7 +432,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { setShowSignalSourceModal(false); } catch (error) { console.error('Failed to save signal source:', error); - alert('保存信号源配置失败'); + alert(t('saveSignalSourceFailed', language)); } }; @@ -493,13 +493,13 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { @@ -899,7 +904,8 @@ function ModelConfigModal({ editingModelId, onSave, onDelete, - onClose + onClose, + language }: { allModels: AIModel[]; configuredModels: AIModel[]; @@ -907,6 +913,7 @@ function ModelConfigModal({ onSave: (modelId: string, apiKey: string, baseUrl?: string) => void; onDelete: (modelId: string) => void; onClose: () => void; + language: Language; }) { const [selectedModelId, setSelectedModelId] = useState(editingModelId || ''); const [apiKey, setApiKey] = useState(''); @@ -940,30 +947,30 @@ function ModelConfigModal({

- {editingModelId ? '编辑AI模型' : '添加AI模型'} + {editingModelId ? t('editAIModel', language) : t('addAIModel', language)}

{editingModelId && ( )}
- +
{!editingModelId && (
setBaseUrl(e.target.value)} - placeholder="自定义API基础URL,如: https://api.openai.com/v1" + placeholder={t('customBaseURLPlaceholder', language)} className="w-full px-3 py-2 rounded" style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }} />
- 留空则使用默认API地址 + {t('leaveBlankForDefault', language)}
- ℹ️ 说明 + ℹ️ {t('information', language)}
-
• API Key将被加密存储,请确保密钥有效
-
• Base URL用于自定义API服务器地址
-
• 删除配置后,使用此模型的交易员将无法正常工作
+
{t('modelConfigInfo1', language)}
+
{t('modelConfigInfo2', language)}
+
{t('modelConfigInfo3', language)}
@@ -1060,7 +1067,7 @@ function ModelConfigModal({ className="flex-1 px-4 py-2 rounded text-sm font-semibold" style={{ background: '#2B3139', color: '#848E9C' }} > - 取消 + {t('cancel', language)}
@@ -1083,13 +1090,15 @@ function ExchangeConfigModal({ editingExchangeId, onSave, onDelete, - onClose + onClose, + language }: { allExchanges: Exchange[]; editingExchangeId: string | null; onSave: (exchangeId: string, apiKey: string, secretKey?: string, testnet?: boolean, hyperliquidWalletAddr?: string, asterUser?: string, asterSigner?: string, asterPrivateKey?: string) => Promise; onDelete: (exchangeId: string) => void; onClose: () => void; + language: Language; }) { const [selectedExchangeId, setSelectedExchangeId] = useState(editingExchangeId || ''); const [apiKey, setApiKey] = useState(''); @@ -1132,30 +1141,30 @@ function ExchangeConfigModal({

- {editingExchangeId ? '编辑交易所' : '添加交易所'} + {editingExchangeId ? t('editExchange', language) : t('addExchange', language)}

{editingExchangeId && ( )}
- +
{!editingExchangeId && (
setModelName(e.target.value)} + placeholder="例如: deepseek-chat, qwen-plus, gpt-4" + className="w-full px-3 py-2 rounded" + style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }} + /> +
+ 留空使用默认模型名称 +
+
+
ℹ️ {t('information', language)} diff --git a/web/src/components/TraderConfigModal.tsx b/web/src/components/TraderConfigModal.tsx index cab3dab7..2ac44aa4 100644 --- a/web/src/components/TraderConfigModal.tsx +++ b/web/src/components/TraderConfigModal.tsx @@ -72,7 +72,7 @@ export function TraderConfigModal({ } else if (!isEditMode) { setFormData({ trader_name: '', - ai_model: availableModels[0]?.id || '', + ai_model: availableModels[0]?.provider || '', exchange_id: availableExchanges[0]?.id || '', btc_eth_leverage: 5, altcoin_leverage: 3, @@ -217,7 +217,7 @@ export function TraderConfigModal({ className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none" > {availableModels.map(model => ( - ))} diff --git a/web/src/types.ts b/web/src/types.ts index 9554a3b3..42d60aad 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -101,6 +101,7 @@ export interface AIModel { enabled: boolean; apiKey?: string; customApiUrl?: string; + customModelName?: string; } export interface Exchange { @@ -140,6 +141,7 @@ export interface UpdateModelConfigRequest { enabled: boolean; api_key: string; custom_api_url?: string; + custom_model_name?: string; }; }; } From 7bc936880c62c8223bdd5b51b5063e6e285ec266 Mon Sep 17 00:00:00 2001 From: SkywalkerJi Date: Sat, 1 Nov 2025 16:25:36 +0800 Subject: [PATCH 10/12] Reordering system prompts. --- decision/engine.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/decision/engine.go b/decision/engine.go index 4f1ae721..89439678 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -250,14 +250,6 @@ func buildSystemPrompt(accountEquity float64, btcEthLeverage, altcoinLeverage in sb.WriteString("关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易!\n") sb.WriteString("大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。\n\n") - // === 硬约束(风险控制)=== - sb.WriteString("# 硬约束(风险控制)\n\n") - sb.WriteString("1. 风险回报比: 必须 ≥ 1:3(冒1%风险,赚3%+收益)\n") - sb.WriteString("2. 最多持仓: 3个币种(质量>数量)\n") - sb.WriteString(fmt.Sprintf("3. 单币仓位: 山寨%.0f-%.0f U(%dx杠杆) | BTC/ETH %.0f-%.0f U(%dx杠杆)\n", - accountEquity*0.8, accountEquity*1.5, altcoinLeverage, accountEquity*5, accountEquity*10, btcEthLeverage)) - sb.WriteString("4. 保证金: 总使用率 ≤ 90%\n\n") - // === 交易哲学 & 最佳实践 === sb.WriteString("# 交易哲学 & 最佳实践\n\n") sb.WriteString("## 核心原则:\n\n") @@ -303,7 +295,7 @@ func buildSystemPrompt(accountEquity float64, btcEthLeverage, altcoinLeverage in sb.WriteString("- 刚平仓不久(<15分钟)\n\n") // === 夏普比率自我进化 === -sb.WriteString("# 夏普比率自我进化\n\n") + sb.WriteString("# 夏普比率自我进化\n\n") sb.WriteString("每次你会收到夏普比率作为绩效反馈(周期级别):\n\n") sb.WriteString("夏普比率 < -0.5 (持续亏损):\n") sb.WriteString(" → 停止交易,连续观望至少6个周期(18分钟)\n") @@ -328,6 +320,21 @@ sb.WriteString("# 夏普比率自我进化\n\n") sb.WriteString("3. 寻找新机会: 有强信号吗?多空机会?\n") sb.WriteString("4. 输出决策: 思维链分析 + JSON\n\n") + // === 关键提醒 === + sb.WriteString("---\n\n") + sb.WriteString("记住: \n") + sb.WriteString("- 目标是夏普比率,不是交易频率\n") + sb.WriteString("- 宁可错过,不做低质量交易\n") + sb.WriteString("- 风险回报比1:3是底线\n") + + // === 硬约束(风险控制)=== + sb.WriteString("# 硬约束(风险控制)\n\n") + sb.WriteString("1. 风险回报比: 必须 ≥ 1:3(冒1%风险,赚3%+收益)\n") + sb.WriteString("2. 最多持仓: 3个币种(质量>数量)\n") + sb.WriteString(fmt.Sprintf("3. 单币仓位: 山寨%.0f-%.0f U(%dx杠杆) | BTC/ETH %.0f-%.0f U(%dx杠杆)\n", + accountEquity*0.8, accountEquity*1.5, altcoinLeverage, accountEquity*5, accountEquity*10, btcEthLeverage)) + sb.WriteString("4. 保证金: 总使用率 ≤ 90%\n\n") + // === 输出格式 === sb.WriteString("#输出格式\n\n") sb.WriteString("第一步: 思维链(纯文本)\n") @@ -342,13 +349,6 @@ sb.WriteString("# 夏普比率自我进化\n\n") sb.WriteString("- `confidence`: 0-100(开仓建议≥75)\n") sb.WriteString("- 开仓时必填: leverage, position_size_usd, stop_loss, take_profit, confidence, risk_usd, reasoning\n\n") - // === 关键提醒 === - sb.WriteString("---\n\n") - sb.WriteString("记住: \n") - sb.WriteString("- 目标是夏普比率,不是交易频率\n") - sb.WriteString("- 宁可错过,不做低质量交易\n") - sb.WriteString("- 风险回报比1:3是底线\n") - return sb.String() } From 5be7106eb2eb1abb77f7b7efa73520ee6aad8453 Mon Sep 17 00:00:00 2001 From: SkywalkerJi Date: Sat, 1 Nov 2025 17:10:36 +0800 Subject: [PATCH 11/12] Rename the model. --- web/src/App.tsx | 6 ------ web/src/components/AITradersPage.tsx | 8 +------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/web/src/App.tsx b/web/src/App.tsx index c6092b5d..a4b627f2 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -31,12 +31,6 @@ function getModelDisplayName(modelId: string): string { return 'Qwen'; case 'claude': return 'Claude'; - case 'gpt4': - case 'gpt-4': - return 'GPT-4'; - case 'gpt3.5': - case 'gpt-3.5': - return 'GPT-3.5'; default: return modelId.toUpperCase(); } diff --git a/web/src/components/AITradersPage.tsx b/web/src/components/AITradersPage.tsx index 69cbb7b3..b47f0b5f 100644 --- a/web/src/components/AITradersPage.tsx +++ b/web/src/components/AITradersPage.tsx @@ -18,12 +18,6 @@ function getModelDisplayName(modelId: string): string { return 'Qwen'; case 'claude': return 'Claude'; - case 'gpt4': - case 'gpt-4': - return 'GPT-4'; - case 'gpt3.5': - case 'gpt-3.5': - return 'GPT-3.5'; default: return modelId.toUpperCase(); } @@ -1060,7 +1054,7 @@ function ModelConfigModal({ type="text" value={modelName} onChange={(e) => setModelName(e.target.value)} - placeholder="例如: deepseek-chat, qwen-plus, gpt-4" + placeholder="例如: deepseek-chat, qwen-max, gpt-5" className="w-full px-3 py-2 rounded" style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }} /> From 4250c11ddf53c701c0d52f4f9520bcb4bfbc29e4 Mon Sep 17 00:00:00 2001 From: SkywalkerJi Date: Sat, 1 Nov 2025 19:45:54 +0800 Subject: [PATCH 12/12] Supports custom system prompts and custom models. --- api/server.go | 101 +++++++--- config/database.go | 109 +++++++---- decision/engine.go | 153 +++++----------- decision/prompt_manager.go | 162 ++++++++++++++++ logger/decision_logger.go | 1 + manager/trader_manager.go | 34 +++- prompts/default.txt | 114 ++++++++++++ prompts/nof1.txt | 223 +++++++++++++++++++++++ trader/auto_trader.go | 93 +++++++--- web/src/components/AITradersPage.tsx | 4 +- web/src/components/TraderConfigModal.tsx | 62 ++++++- web/src/types.ts | 1 + 12 files changed, 848 insertions(+), 209 deletions(-) create mode 100644 decision/prompt_manager.go create mode 100644 prompts/default.txt create mode 100644 prompts/nof1.txt diff --git a/api/server.go b/api/server.go index 3a5e645e..110f0a9c 100644 --- a/api/server.go +++ b/api/server.go @@ -7,6 +7,7 @@ import ( "net/http" "nofx/auth" "nofx/config" + "nofx/decision" "nofx/manager" "strconv" "strings" @@ -109,6 +110,10 @@ func (s *Server) setupRoutes() { protected.GET("/user/signal-sources", s.handleGetUserSignalSource) protected.POST("/user/signal-sources", s.handleSaveUserSignalSource) + // 系统提示词模板管理 + protected.GET("/prompt-templates", s.handleGetPromptTemplates) + protected.GET("/prompt-templates/:name", s.handleGetPromptTemplate) + // 竞赛总览 protected.GET("/competition", s.handleCompetition) @@ -200,18 +205,19 @@ func (s *Server) getTraderFromQuery(c *gin.Context) (*manager.TraderManager, str // AI交易员管理相关结构体 type CreateTraderRequest struct { - Name string `json:"name" binding:"required"` - AIModelID string `json:"ai_model_id" binding:"required"` - ExchangeID string `json:"exchange_id" binding:"required"` - InitialBalance float64 `json:"initial_balance"` - BTCETHLeverage int `json:"btc_eth_leverage"` - AltcoinLeverage int `json:"altcoin_leverage"` - TradingSymbols string `json:"trading_symbols"` - CustomPrompt string `json:"custom_prompt"` - OverrideBasePrompt bool `json:"override_base_prompt"` - IsCrossMargin *bool `json:"is_cross_margin"` // 指针类型,nil表示使用默认值true - UseCoinPool bool `json:"use_coin_pool"` - UseOITop bool `json:"use_oi_top"` + Name string `json:"name" binding:"required"` + AIModelID string `json:"ai_model_id" binding:"required"` + ExchangeID string `json:"exchange_id" binding:"required"` + InitialBalance float64 `json:"initial_balance"` + BTCETHLeverage int `json:"btc_eth_leverage"` + AltcoinLeverage int `json:"altcoin_leverage"` + TradingSymbols string `json:"trading_symbols"` + CustomPrompt string `json:"custom_prompt"` + OverrideBasePrompt bool `json:"override_base_prompt"` + SystemPromptTemplate string `json:"system_prompt_template"` // 系统提示词模板名称 + IsCrossMargin *bool `json:"is_cross_margin"` // 指针类型,nil表示使用默认值true + UseCoinPool bool `json:"use_coin_pool"` + UseOITop bool `json:"use_oi_top"` } type ModelConfig struct { @@ -319,23 +325,30 @@ func (s *Server) handleCreateTrader(c *gin.Context) { } } + // 设置系统提示词模板默认值 + systemPromptTemplate := "default" + if req.SystemPromptTemplate != "" { + systemPromptTemplate = req.SystemPromptTemplate + } + // 创建交易员配置(数据库实体) trader := &config.TraderRecord{ - ID: traderID, - UserID: userID, - Name: req.Name, - AIModelID: req.AIModelID, - ExchangeID: req.ExchangeID, - InitialBalance: req.InitialBalance, - BTCETHLeverage: btcEthLeverage, - AltcoinLeverage: altcoinLeverage, - TradingSymbols: req.TradingSymbols, - UseCoinPool: req.UseCoinPool, - UseOITop: req.UseOITop, - CustomPrompt: req.CustomPrompt, - OverrideBasePrompt: req.OverrideBasePrompt, - IsCrossMargin: isCrossMargin, - ScanIntervalMinutes: 3, // 默认3分钟 + ID: traderID, + UserID: userID, + Name: req.Name, + AIModelID: req.AIModelID, + ExchangeID: req.ExchangeID, + InitialBalance: req.InitialBalance, + BTCETHLeverage: btcEthLeverage, + AltcoinLeverage: altcoinLeverage, + TradingSymbols: req.TradingSymbols, + UseCoinPool: req.UseCoinPool, + UseOITop: req.UseOITop, + CustomPrompt: req.CustomPrompt, + OverrideBasePrompt: req.OverrideBasePrompt, + SystemPromptTemplate: systemPromptTemplate, + IsCrossMargin: isCrossMargin, + ScanIntervalMinutes: 3, // 默认3分钟 IsRunning: false, } @@ -1407,3 +1420,37 @@ func (s *Server) Start() error { return s.router.Run(addr) } + +// handleGetPromptTemplates 获取所有系统提示词模板列表 +func (s *Server) handleGetPromptTemplates(c *gin.Context) { + // 导入 decision 包 + templates := decision.GetAllPromptTemplates() + + // 转换为响应格式 + response := make([]map[string]interface{}, 0, len(templates)) + for _, tmpl := range templates { + response = append(response, map[string]interface{}{ + "name": tmpl.Name, + }) + } + + c.JSON(http.StatusOK, gin.H{ + "templates": response, + }) +} + +// handleGetPromptTemplate 获取指定名称的提示词模板内容 +func (s *Server) handleGetPromptTemplate(c *gin.Context) { + templateName := c.Param("name") + + template, err := decision.GetPromptTemplate(templateName) + if err != nil { + c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("模板不存在: %s", templateName)}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "name": template.Name, + "content": template.Content, + }) +} diff --git a/config/database.go b/config/database.go index a056db88..624433bc 100644 --- a/config/database.go +++ b/config/database.go @@ -6,6 +6,7 @@ import ( "encoding/base32" "fmt" "log" + "strings" "time" _ "github.com/mattn/go-sqlite3" @@ -182,10 +183,11 @@ func (d *Database) createTables() error { `ALTER TABLE traders ADD COLUMN btc_eth_leverage INTEGER DEFAULT 5`, // BTC/ETH杠杆倍数 `ALTER TABLE traders ADD COLUMN altcoin_leverage INTEGER DEFAULT 5`, // 山寨币杠杆倍数 `ALTER TABLE traders ADD COLUMN trading_symbols TEXT DEFAULT ''`, // 交易币种,逗号分隔 - `ALTER TABLE traders ADD COLUMN use_coin_pool BOOLEAN DEFAULT 0`, // 是否使用COIN POOL信号源 - `ALTER TABLE traders ADD COLUMN use_oi_top BOOLEAN DEFAULT 0`, // 是否使用OI TOP信号源 - `ALTER TABLE ai_models ADD COLUMN custom_api_url TEXT DEFAULT ''`, // 自定义API地址 - `ALTER TABLE ai_models ADD COLUMN custom_model_name TEXT DEFAULT ''`, // 自定义模型名称 + `ALTER TABLE traders ADD COLUMN use_coin_pool BOOLEAN DEFAULT 0`, // 是否使用COIN POOL信号源 + `ALTER TABLE traders ADD COLUMN use_oi_top BOOLEAN DEFAULT 0`, // 是否使用OI TOP信号源 + `ALTER TABLE traders ADD COLUMN system_prompt_template TEXT DEFAULT 'default'`, // 系统提示词模板名称 + `ALTER TABLE ai_models ADD COLUMN custom_api_url TEXT DEFAULT ''`, // 自定义API地址 + `ALTER TABLE ai_models ADD COLUMN custom_model_name TEXT DEFAULT ''`, // 自定义模型名称 } for _, query := range alterQueries { @@ -407,14 +409,15 @@ type TraderRecord struct { IsRunning bool `json:"is_running"` BTCETHLeverage int `json:"btc_eth_leverage"` // BTC/ETH杠杆倍数 AltcoinLeverage int `json:"altcoin_leverage"` // 山寨币杠杆倍数 - TradingSymbols string `json:"trading_symbols"` // 交易币种,逗号分隔 - UseCoinPool bool `json:"use_coin_pool"` // 是否使用COIN POOL信号源 - UseOITop bool `json:"use_oi_top"` // 是否使用OI TOP信号源 - CustomPrompt string `json:"custom_prompt"` // 自定义交易策略prompt - OverrideBasePrompt bool `json:"override_base_prompt"` // 是否覆盖基础prompt - IsCrossMargin bool `json:"is_cross_margin"` // 是否为全仓模式(true=全仓,false=逐仓) - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + TradingSymbols string `json:"trading_symbols"` // 交易币种,逗号分隔 + UseCoinPool bool `json:"use_coin_pool"` // 是否使用COIN POOL信号源 + UseOITop bool `json:"use_oi_top"` // 是否使用OI TOP信号源 + CustomPrompt string `json:"custom_prompt"` // 自定义交易策略prompt + OverrideBasePrompt bool `json:"override_base_prompt"` // 是否覆盖基础prompt + SystemPromptTemplate string `json:"system_prompt_template"` // 系统提示词模板名称 + IsCrossMargin bool `json:"is_cross_margin"` // 是否为全仓模式(true=全仓,false=逐仓) + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } // UserSignalSource 用户信号源配置 @@ -563,17 +566,14 @@ func (d *Database) GetAIModels(userID string) ([]*AIModelConfig, error) { // UpdateAIModel 更新AI模型配置,如果不存在则创建用户特定配置 func (d *Database) UpdateAIModel(userID, id string, enabled bool, apiKey, customAPIURL, customModelName string) error { - // id 参数实际上是 provider(如 "deepseek", "qwen") - provider := id - - // 先查找用户是否已有这个 provider 的配置 + // 先尝试精确匹配 ID(新版逻辑,支持多个相同 provider 的模型) var existingID string err := d.db.QueryRow(` - SELECT id FROM ai_models WHERE user_id = ? AND provider = ? LIMIT 1 - `, userID, provider).Scan(&existingID) + SELECT id FROM ai_models WHERE user_id = ? AND id = ? LIMIT 1 + `, userID, id).Scan(&existingID) if err == nil { - // 找到了现有配置,更新它 + // 找到了现有配置(精确匹配 ID),更新它 _, err = d.db.Exec(` UPDATE ai_models SET enabled = ?, api_key = ?, custom_api_url = ?, custom_model_name = ?, updated_at = datetime('now') WHERE id = ? AND user_id = ? @@ -581,7 +581,37 @@ func (d *Database) UpdateAIModel(userID, id string, enabled bool, apiKey, custom return err } - // 没有找到现有配置,创建新的 + // ID 不存在,尝试兼容旧逻辑:将 id 作为 provider 查找 + provider := id + err = d.db.QueryRow(` + SELECT id FROM ai_models WHERE user_id = ? AND provider = ? LIMIT 1 + `, userID, provider).Scan(&existingID) + + if err == nil { + // 找到了现有配置(通过 provider 匹配,兼容旧版),更新它 + log.Printf("⚠️ 使用旧版 provider 匹配更新模型: %s -> %s", provider, existingID) + _, err = d.db.Exec(` + UPDATE ai_models SET enabled = ?, api_key = ?, custom_api_url = ?, custom_model_name = ?, updated_at = datetime('now') + WHERE id = ? AND user_id = ? + `, enabled, apiKey, customAPIURL, customModelName, existingID, userID) + return err + } + + // 没有找到任何现有配置,创建新的 + // 推断 provider(从 id 中提取,或者直接使用 id) + if provider == id && (provider == "deepseek" || provider == "qwen") { + // id 本身就是 provider + provider = id + } else { + // 从 id 中提取 provider(假设格式是 userID_provider 或 timestamp_userID_provider) + parts := strings.Split(id, "_") + if len(parts) >= 2 { + provider = parts[len(parts)-1] // 取最后一部分作为 provider + } else { + provider = id + } + } + // 获取模型的基本信息 var name string err = d.db.QueryRow(` @@ -598,12 +628,19 @@ func (d *Database) UpdateAIModel(userID, id string, enabled bool, apiKey, custom } } - // 创建用户特定的配置 - userModelID := fmt.Sprintf("%s_%s", userID, provider) + // 如果传入的 ID 已经是完整格式(如 "admin_deepseek_custom1"),直接使用 + // 否则生成新的 ID + newModelID := id + if id == provider { + // id 就是 provider,生成新的用户特定 ID + newModelID = fmt.Sprintf("%s_%s", userID, provider) + } + + log.Printf("✓ 创建新的 AI 模型配置: ID=%s, Provider=%s, Name=%s", newModelID, provider, name) _, err = d.db.Exec(` INSERT INTO ai_models (id, user_id, name, provider, enabled, api_key, custom_api_url, custom_model_name, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now')) - `, userModelID, userID, name, provider, enabled, apiKey, customAPIURL, customModelName) + `, newModelID, userID, name, provider, enabled, apiKey, customAPIURL, customModelName) return err } @@ -730,20 +767,21 @@ func (d *Database) CreateExchange(userID, id, name, typ string, enabled bool, ap // CreateTrader 创建交易员 func (d *Database) CreateTrader(trader *TraderRecord) error { _, err := d.db.Exec(` - INSERT INTO traders (id, user_id, name, ai_model_id, exchange_id, initial_balance, scan_interval_minutes, is_running, btc_eth_leverage, altcoin_leverage, trading_symbols, use_coin_pool, use_oi_top, custom_prompt, override_base_prompt, is_cross_margin) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - `, trader.ID, trader.UserID, trader.Name, trader.AIModelID, trader.ExchangeID, trader.InitialBalance, trader.ScanIntervalMinutes, trader.IsRunning, trader.BTCETHLeverage, trader.AltcoinLeverage, trader.TradingSymbols, trader.UseCoinPool, trader.UseOITop, trader.CustomPrompt, trader.OverrideBasePrompt, trader.IsCrossMargin) + INSERT INTO traders (id, user_id, name, ai_model_id, exchange_id, initial_balance, scan_interval_minutes, is_running, btc_eth_leverage, altcoin_leverage, trading_symbols, use_coin_pool, use_oi_top, custom_prompt, override_base_prompt, system_prompt_template, is_cross_margin) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `, trader.ID, trader.UserID, trader.Name, trader.AIModelID, trader.ExchangeID, trader.InitialBalance, trader.ScanIntervalMinutes, trader.IsRunning, trader.BTCETHLeverage, trader.AltcoinLeverage, trader.TradingSymbols, trader.UseCoinPool, trader.UseOITop, trader.CustomPrompt, trader.OverrideBasePrompt, trader.SystemPromptTemplate, trader.IsCrossMargin) return err } // GetTraders 获取用户的交易员 func (d *Database) GetTraders(userID string) ([]*TraderRecord, error) { rows, err := d.db.Query(` - SELECT id, user_id, name, ai_model_id, exchange_id, initial_balance, scan_interval_minutes, is_running, + SELECT id, user_id, name, ai_model_id, exchange_id, initial_balance, scan_interval_minutes, is_running, COALESCE(btc_eth_leverage, 5) as btc_eth_leverage, COALESCE(altcoin_leverage, 5) as altcoin_leverage, COALESCE(trading_symbols, '') as trading_symbols, COALESCE(use_coin_pool, 0) as use_coin_pool, COALESCE(use_oi_top, 0) as use_oi_top, - COALESCE(custom_prompt, '') as custom_prompt, COALESCE(override_base_prompt, 0) as override_base_prompt, + COALESCE(custom_prompt, '') as custom_prompt, COALESCE(override_base_prompt, 0) as override_base_prompt, + COALESCE(system_prompt_template, 'default') as system_prompt_template, COALESCE(is_cross_margin, 1) as is_cross_margin, created_at, updated_at FROM traders WHERE user_id = ? ORDER BY created_at DESC `, userID) @@ -760,7 +798,8 @@ func (d *Database) GetTraders(userID string) ([]*TraderRecord, error) { &trader.InitialBalance, &trader.ScanIntervalMinutes, &trader.IsRunning, &trader.BTCETHLeverage, &trader.AltcoinLeverage, &trader.TradingSymbols, &trader.UseCoinPool, &trader.UseOITop, - &trader.CustomPrompt, &trader.OverrideBasePrompt, &trader.IsCrossMargin, + &trader.CustomPrompt, &trader.OverrideBasePrompt, &trader.SystemPromptTemplate, + &trader.IsCrossMargin, &trader.CreatedAt, &trader.UpdatedAt, ) if err != nil { @@ -781,16 +820,16 @@ func (d *Database) UpdateTraderStatus(userID, id string, isRunning bool) error { // UpdateTrader 更新交易员配置 func (d *Database) UpdateTrader(trader *TraderRecord) error { _, err := d.db.Exec(` - UPDATE traders SET - name = ?, ai_model_id = ?, exchange_id = ?, initial_balance = ?, - scan_interval_minutes = ?, btc_eth_leverage = ?, altcoin_leverage = ?, - trading_symbols = ?, custom_prompt = ?, override_base_prompt = ?, - is_cross_margin = ?, updated_at = CURRENT_TIMESTAMP + UPDATE traders SET + name = ?, ai_model_id = ?, exchange_id = ?, initial_balance = ?, + scan_interval_minutes = ?, btc_eth_leverage = ?, altcoin_leverage = ?, + trading_symbols = ?, custom_prompt = ?, override_base_prompt = ?, + system_prompt_template = ?, is_cross_margin = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? AND user_id = ? `, trader.Name, trader.AIModelID, trader.ExchangeID, trader.InitialBalance, trader.ScanIntervalMinutes, trader.BTCETHLeverage, trader.AltcoinLeverage, trader.TradingSymbols, trader.CustomPrompt, trader.OverrideBasePrompt, - trader.IsCrossMargin, trader.ID, trader.UserID) + trader.SystemPromptTemplate, trader.IsCrossMargin, trader.ID, trader.UserID) return err } diff --git a/decision/engine.go b/decision/engine.go index 89439678..174ff7d1 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -83,26 +83,27 @@ type Decision struct { // FullDecision AI的完整决策(包含思维链) type FullDecision struct { - UserPrompt string `json:"user_prompt"` // 发送给AI的输入prompt - CoTTrace string `json:"cot_trace"` // 思维链分析(AI输出) - Decisions []Decision `json:"decisions"` // 具体决策列表 - Timestamp time.Time `json:"timestamp"` + SystemPrompt string `json:"system_prompt"` // 系统提示词(发送给AI的系统prompt) + UserPrompt string `json:"user_prompt"` // 发送给AI的输入prompt + CoTTrace string `json:"cot_trace"` // 思维链分析(AI输出) + Decisions []Decision `json:"decisions"` // 具体决策列表 + Timestamp time.Time `json:"timestamp"` } // GetFullDecision 获取AI的完整交易决策(批量分析所有币种和持仓) func GetFullDecision(ctx *Context, mcpClient *mcp.Client) (*FullDecision, error) { - return GetFullDecisionWithCustomPrompt(ctx, mcpClient, "", false) + return GetFullDecisionWithCustomPrompt(ctx, mcpClient, "", false, "") } -// GetFullDecisionWithCustomPrompt 获取AI的完整交易决策(支持自定义prompt) -func GetFullDecisionWithCustomPrompt(ctx *Context, mcpClient *mcp.Client, customPrompt string, overrideBase bool) (*FullDecision, error) { +// GetFullDecisionWithCustomPrompt 获取AI的完整交易决策(支持自定义prompt和模板选择) +func GetFullDecisionWithCustomPrompt(ctx *Context, mcpClient *mcp.Client, customPrompt string, overrideBase bool, templateName string) (*FullDecision, error) { // 1. 为所有币种获取市场数据 if err := fetchMarketDataForContext(ctx); err != nil { return nil, fmt.Errorf("获取市场数据失败: %w", err) } // 2. 构建 System Prompt(固定规则)和 User Prompt(动态数据) - systemPrompt := buildSystemPromptWithCustom(ctx.Account.TotalEquity, ctx.BTCETHLeverage, ctx.AltcoinLeverage, customPrompt, overrideBase) + systemPrompt := buildSystemPromptWithCustom(ctx.Account.TotalEquity, ctx.BTCETHLeverage, ctx.AltcoinLeverage, customPrompt, overrideBase, templateName) userPrompt := buildUserPrompt(ctx) // 3. 调用AI API(使用 system + user prompt) @@ -118,7 +119,8 @@ func GetFullDecisionWithCustomPrompt(ctx *Context, mcpClient *mcp.Client, custom } decision.Timestamp = time.Now() - decision.UserPrompt = userPrompt // 保存输入prompt + decision.SystemPrompt = systemPrompt // 保存系统prompt + decision.UserPrompt = userPrompt // 保存输入prompt return decision, nil } @@ -205,20 +207,20 @@ func calculateMaxCandidates(ctx *Context) int { } // buildSystemPromptWithCustom 构建包含自定义内容的 System Prompt -func buildSystemPromptWithCustom(accountEquity float64, btcEthLeverage, altcoinLeverage int, customPrompt string, overrideBase bool) string { +func buildSystemPromptWithCustom(accountEquity float64, btcEthLeverage, altcoinLeverage int, customPrompt string, overrideBase bool, templateName string) string { // 如果覆盖基础prompt且有自定义prompt,只使用自定义prompt if overrideBase && customPrompt != "" { return customPrompt } - - // 获取基础prompt - basePrompt := buildSystemPrompt(accountEquity, btcEthLeverage, altcoinLeverage) - + + // 获取基础prompt(使用指定的模板) + basePrompt := buildSystemPrompt(accountEquity, btcEthLeverage, altcoinLeverage, templateName) + // 如果没有自定义prompt,直接返回基础prompt if customPrompt == "" { return basePrompt } - + // 添加自定义prompt部分到基础prompt var sb strings.Builder sb.WriteString(basePrompt) @@ -227,107 +229,38 @@ func buildSystemPromptWithCustom(accountEquity float64, btcEthLeverage, altcoinL sb.WriteString(customPrompt) sb.WriteString("\n\n") sb.WriteString("注意: 以上个性化策略是对基础规则的补充,不能违背基础风险控制原则。\n") - + return sb.String() } -// buildSystemPrompt 构建 System Prompt(固定规则,可缓存) -func buildSystemPrompt(accountEquity float64, btcEthLeverage, altcoinLeverage int) string { +// buildSystemPrompt 构建 System Prompt(使用模板+动态部分) +func buildSystemPrompt(accountEquity float64, btcEthLeverage, altcoinLeverage int, templateName string) string { var sb strings.Builder - // === 核心使命 === - sb.WriteString("你是专业的加密货币交易AI,在合约市场进行自主交易。\n\n") - sb.WriteString("# 核心目标\n\n") - sb.WriteString("最大化夏普比率(Sharpe Ratio)\n\n") - sb.WriteString("夏普比率 = 平均收益 / 收益波动率\n\n") - sb.WriteString("这意味着:\n") - sb.WriteString("- 高质量交易(高胜率、大盈亏比)→ 提升夏普\n") - sb.WriteString("- 稳定收益、控制回撤 → 提升夏普\n") - sb.WriteString("- 耐心持仓、让利润奔跑 → 提升夏普\n") - sb.WriteString("- 频繁交易、小盈小亏 → 增加波动,严重降低夏普\n") - sb.WriteString("- 过度交易、手续费损耗 → 直接亏损\n") - sb.WriteString("- 过早平仓、频繁进出 → 错失大行情\n\n") - sb.WriteString("关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易!\n") - sb.WriteString("大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。\n\n") + // 1. 加载提示词模板(核心交易策略部分) + if templateName == "" { + templateName = "default" // 默认使用 default 模板 + } - // === 交易哲学 & 最佳实践 === - sb.WriteString("# 交易哲学 & 最佳实践\n\n") - sb.WriteString("## 核心原则:\n\n") - sb.WriteString("资金保全第一:保护资本比追求收益更重要\n\n") - sb.WriteString("纪律胜于情绪:执行你的退出方案,不随意移动止损或目标\n\n") - sb.WriteString("质量优于数量:少量高信念交易胜过大量低信念交易\n\n") - sb.WriteString("适应波动性:根据市场条件调整仓位\n\n") - sb.WriteString("尊重趋势:不要与强趋势作对\n\n") - sb.WriteString("## 常见误区避免:\n\n") - sb.WriteString("过度交易:频繁交易导致费用侵蚀利润\n\n") - sb.WriteString("复仇式交易:亏损后立即加码试图\"翻本\"\n\n") - sb.WriteString("分析瘫痪:过度等待完美信号,导致失机\n\n") - sb.WriteString("忽视相关性:BTC常引领山寨币,须优先观察BTC\n\n") - sb.WriteString("过度杠杆:放大收益同时放大亏损\n\n") + template, err := GetPromptTemplate(templateName) + if err != nil { + // 如果模板不存在,记录错误并使用 default + log.Printf("⚠️ 提示词模板 '%s' 不存在,使用 default: %v", templateName, err) + template, err = GetPromptTemplate("default") + if err != nil { + // 如果连 default 都不存在,使用内置的简化版本 + log.Printf("❌ 无法加载任何提示词模板,使用内置简化版本") + sb.WriteString("你是专业的加密货币交易AI。请根据市场数据做出交易决策。\n\n") + } else { + sb.WriteString(template.Content) + sb.WriteString("\n\n") + } + } else { + sb.WriteString(template.Content) + sb.WriteString("\n\n") + } - // === 交易频率认知 === - sb.WriteString("#交易频率认知\n\n") - sb.WriteString("量化标准:\n") - sb.WriteString("- 优秀交易员:每天2-4笔 = 每小时0.1-0.2笔\n") - sb.WriteString("- 过度交易:每小时>2笔 = 严重问题\n") - sb.WriteString("- 最佳节奏:开仓后持有至少30-60分钟\n\n") - sb.WriteString("自查:\n") - sb.WriteString("如果你发现自己每个周期都在交易 → 说明标准太低\n") - sb.WriteString("如果你发现持仓<30分钟就平仓 → 说明太急躁\n\n") - - // === 开仓信号强度 === - sb.WriteString("# 开仓标准(严格)\n\n") - sb.WriteString("只在强信号时开仓,不确定就观望。\n\n") - sb.WriteString("你拥有的完整数据:\n") - sb.WriteString("- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列\n") - sb.WriteString("- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列\n") - sb.WriteString("- 资金序列:成交量序列、持仓量(OI)序列、资金费率\n") - sb.WriteString("- 筛选标记:AI500评分 / OI_Top排名(如果有标注)\n\n") - sb.WriteString("分析方法(完全由你自主决定):\n") - sb.WriteString("- 自由运用序列数据,你可以做但不限于趋势分析、形态识别、支撑阻力、技术阻力位、斐波那契、波动带计算\n") - sb.WriteString("- 多维度交叉验证(价格+量+OI+指标+序列形态)\n") - sb.WriteString("- 用你认为最有效的方法发现高确定性机会\n") - sb.WriteString("- 综合信心度 ≥ 75 才开仓\n\n") - sb.WriteString("避免低质量信号:\n") - sb.WriteString("- 单一维度(只看一个指标)\n") - sb.WriteString("- 相互矛盾(涨但量萎缩)\n") - sb.WriteString("- 横盘震荡\n") - sb.WriteString("- 刚平仓不久(<15分钟)\n\n") - - // === 夏普比率自我进化 === - sb.WriteString("# 夏普比率自我进化\n\n") - sb.WriteString("每次你会收到夏普比率作为绩效反馈(周期级别):\n\n") - sb.WriteString("夏普比率 < -0.5 (持续亏损):\n") - sb.WriteString(" → 停止交易,连续观望至少6个周期(18分钟)\n") - sb.WriteString(" → 深度反思:\n") - sb.WriteString(" • 交易频率过高?(每小时>2次就是过度)\n") - sb.WriteString(" • 持仓时间过短?(<30分钟就是过早平仓)\n") - sb.WriteString(" • 信号强度不足?(信心度<75)\n") - sb.WriteString("夏普比率 -0.5 ~ 0 (轻微亏损):\n") - sb.WriteString(" → 严格控制:只做信心度>80的交易\n") - sb.WriteString(" → 减少交易频率:每小时最多1笔新开仓\n") - sb.WriteString(" → 耐心持仓:至少持有30分钟以上\n\n") - sb.WriteString("夏普比率 0 ~ 0.7 (正收益):\n") - sb.WriteString(" → 维持当前策略\n\n") - sb.WriteString("夏普比率 > 0.7 (优异表现):\n") - sb.WriteString(" → 可适度扩大仓位\n\n") - sb.WriteString("关键: 夏普比率是唯一指标,它会自然惩罚频繁交易和过度进出。\n\n") - - // === 决策流程 === - sb.WriteString("#决策流程\n\n") - sb.WriteString("1. 分析夏普比率: 当前策略是否有效?需要调整吗?\n") - sb.WriteString("2. 评估持仓: 趋势是否改变?是否该止盈/止损?\n") - sb.WriteString("3. 寻找新机会: 有强信号吗?多空机会?\n") - sb.WriteString("4. 输出决策: 思维链分析 + JSON\n\n") - - // === 关键提醒 === - sb.WriteString("---\n\n") - sb.WriteString("记住: \n") - sb.WriteString("- 目标是夏普比率,不是交易频率\n") - sb.WriteString("- 宁可错过,不做低质量交易\n") - sb.WriteString("- 风险回报比1:3是底线\n") - - // === 硬约束(风险控制)=== + // 2. 硬约束(风险控制)- 动态生成 sb.WriteString("# 硬约束(风险控制)\n\n") sb.WriteString("1. 风险回报比: 必须 ≥ 1:3(冒1%风险,赚3%+收益)\n") sb.WriteString("2. 最多持仓: 3个币种(质量>数量)\n") @@ -335,7 +268,7 @@ func buildSystemPrompt(accountEquity float64, btcEthLeverage, altcoinLeverage in accountEquity*0.8, accountEquity*1.5, altcoinLeverage, accountEquity*5, accountEquity*10, btcEthLeverage)) sb.WriteString("4. 保证金: 总使用率 ≤ 90%\n\n") - // === 输出格式 === + // 3. 输出格式 - 动态生成 sb.WriteString("#输出格式\n\n") sb.WriteString("第一步: 思维链(纯文本)\n") sb.WriteString("简洁分析你的思考过程\n\n") diff --git a/decision/prompt_manager.go b/decision/prompt_manager.go new file mode 100644 index 00000000..3bece5ea --- /dev/null +++ b/decision/prompt_manager.go @@ -0,0 +1,162 @@ +package decision + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + "sync" +) + +// PromptTemplate 系统提示词模板 +type PromptTemplate struct { + Name string // 模板名称(文件名,不含扩展名) + Content string // 模板内容 +} + +// PromptManager 提示词管理器 +type PromptManager struct { + templates map[string]*PromptTemplate + mu sync.RWMutex +} + +var ( + // globalPromptManager 全局提示词管理器 + globalPromptManager *PromptManager + // promptsDir 提示词文件夹路径 + promptsDir = "prompts" +) + +// init 包初始化时加载所有提示词模板 +func init() { + globalPromptManager = NewPromptManager() + if err := globalPromptManager.LoadTemplates(promptsDir); err != nil { + log.Printf("⚠️ 加载提示词模板失败: %v", err) + } else { + log.Printf("✓ 已加载 %d 个系统提示词模板", len(globalPromptManager.templates)) + } +} + +// NewPromptManager 创建提示词管理器 +func NewPromptManager() *PromptManager { + return &PromptManager{ + templates: make(map[string]*PromptTemplate), + } +} + +// LoadTemplates 从指定目录加载所有提示词模板 +func (pm *PromptManager) LoadTemplates(dir string) error { + pm.mu.Lock() + defer pm.mu.Unlock() + + // 检查目录是否存在 + if _, err := os.Stat(dir); os.IsNotExist(err) { + return fmt.Errorf("提示词目录不存在: %s", dir) + } + + // 扫描目录中的所有 .txt 文件 + files, err := filepath.Glob(filepath.Join(dir, "*.txt")) + if err != nil { + return fmt.Errorf("扫描提示词目录失败: %w", err) + } + + if len(files) == 0 { + log.Printf("⚠️ 提示词目录 %s 中没有找到 .txt 文件", dir) + return nil + } + + // 加载每个模板文件 + for _, file := range files { + // 读取文件内容 + content, err := os.ReadFile(file) + if err != nil { + log.Printf("⚠️ 读取提示词文件失败 %s: %v", file, err) + continue + } + + // 提取文件名(不含扩展名)作为模板名称 + fileName := filepath.Base(file) + templateName := strings.TrimSuffix(fileName, filepath.Ext(fileName)) + + // 存储模板 + pm.templates[templateName] = &PromptTemplate{ + Name: templateName, + Content: string(content), + } + + log.Printf(" 📄 加载提示词模板: %s (%s)", templateName, fileName) + } + + return nil +} + +// GetTemplate 获取指定名称的提示词模板 +func (pm *PromptManager) GetTemplate(name string) (*PromptTemplate, error) { + pm.mu.RLock() + defer pm.mu.RUnlock() + + template, exists := pm.templates[name] + if !exists { + return nil, fmt.Errorf("提示词模板不存在: %s", name) + } + + return template, nil +} + +// GetAllTemplateNames 获取所有模板名称列表 +func (pm *PromptManager) GetAllTemplateNames() []string { + pm.mu.RLock() + defer pm.mu.RUnlock() + + names := make([]string, 0, len(pm.templates)) + for name := range pm.templates { + names = append(names, name) + } + + return names +} + +// GetAllTemplates 获取所有模板 +func (pm *PromptManager) GetAllTemplates() []*PromptTemplate { + pm.mu.RLock() + defer pm.mu.RUnlock() + + templates := make([]*PromptTemplate, 0, len(pm.templates)) + for _, template := range pm.templates { + templates = append(templates, template) + } + + return templates +} + +// ReloadTemplates 重新加载所有模板 +func (pm *PromptManager) ReloadTemplates(dir string) error { + pm.mu.Lock() + pm.templates = make(map[string]*PromptTemplate) + pm.mu.Unlock() + + return pm.LoadTemplates(dir) +} + +// === 全局函数(供外部调用)=== + +// GetPromptTemplate 获取指定名称的提示词模板(全局函数) +func GetPromptTemplate(name string) (*PromptTemplate, error) { + return globalPromptManager.GetTemplate(name) +} + +// GetAllPromptTemplateNames 获取所有模板名称(全局函数) +func GetAllPromptTemplateNames() []string { + return globalPromptManager.GetAllTemplateNames() +} + +// GetAllPromptTemplates 获取所有模板(全局函数) +func GetAllPromptTemplates() []*PromptTemplate { + return globalPromptManager.GetAllTemplates() +} + +// ReloadPromptTemplates 重新加载所有模板(全局函数) +func ReloadPromptTemplates() error { + return globalPromptManager.ReloadTemplates(promptsDir) +} diff --git a/logger/decision_logger.go b/logger/decision_logger.go index ed446f20..efa5ab74 100644 --- a/logger/decision_logger.go +++ b/logger/decision_logger.go @@ -14,6 +14,7 @@ import ( type DecisionRecord struct { Timestamp time.Time `json:"timestamp"` // 决策时间 CycleNumber int `json:"cycle_number"` // 周期编号 + SystemPrompt string `json:"system_prompt"` // 系统提示词(发送给AI的系统prompt) InputPrompt string `json:"input_prompt"` // 发送给AI的输入prompt CoTTrace string `json:"cot_trace"` // AI思维链(输出) DecisionJSON string `json:"decision_json"` // 决策JSON diff --git a/manager/trader_manager.go b/manager/trader_manager.go index e55b4acf..d3861cdb 100644 --- a/manager/trader_manager.go +++ b/manager/trader_manager.go @@ -93,14 +93,23 @@ func (tm *TraderManager) LoadTradersFromDatabase(database *config.Database) erro } var aiModelCfg *config.AIModelConfig + // 优先精确匹配 model.ID(新版逻辑) for _, model := range aiModels { - // 使用 provider 来匹配,因为 AIModelID 存储的是 provider(如 "deepseek") - // 而 model.ID 可能是 "admin_deepseek" - if model.Provider == traderCfg.AIModelID { + if model.ID == traderCfg.AIModelID { aiModelCfg = model break } } + // 如果没有精确匹配,尝试匹配 provider(兼容旧数据) + if aiModelCfg == nil { + for _, model := range aiModels { + if model.Provider == traderCfg.AIModelID { + aiModelCfg = model + log.Printf("⚠️ 交易员 %s 使用旧版 provider 匹配: %s -> %s", traderCfg.Name, traderCfg.AIModelID, model.ID) + break + } + } + } if aiModelCfg == nil { log.Printf("⚠️ 交易员 %s 的AI模型 %s 不存在,跳过", traderCfg.Name, traderCfg.AIModelID) @@ -216,6 +225,7 @@ func (tm *TraderManager) addTraderFromDB(traderCfg *config.TraderRecord, aiModel IsCrossMargin: traderCfg.IsCrossMargin, DefaultCoins: defaultCoins, TradingCoins: tradingCoins, + SystemPromptTemplate: traderCfg.SystemPromptTemplate, // 系统提示词模板 } // 根据交易所类型设置API密钥 @@ -621,13 +631,23 @@ func (tm *TraderManager) LoadUserTraders(database *config.Database, userID strin } var aiModelCfg *config.AIModelConfig + // 优先精确匹配 model.ID(新版逻辑) for _, model := range aiModels { - // 使用 provider 来匹配,因为 AIModelID 存储的是 provider(如 "deepseek") - if model.Provider == traderCfg.AIModelID { + if model.ID == traderCfg.AIModelID { aiModelCfg = model break } } + // 如果没有精确匹配,尝试匹配 provider(兼容旧数据) + if aiModelCfg == nil { + for _, model := range aiModels { + if model.Provider == traderCfg.AIModelID { + aiModelCfg = model + log.Printf("⚠️ 交易员 %s 使用旧版 provider 匹配: %s -> %s", traderCfg.Name, traderCfg.AIModelID, model.ID) + break + } + } + } if aiModelCfg == nil { log.Printf("⚠️ 交易员 %s 的AI模型 %s 不存在,跳过", traderCfg.Name, traderCfg.AIModelID) @@ -712,12 +732,16 @@ func (tm *TraderManager) loadSingleTrader(traderCfg *config.TraderRecord, aiMode AltcoinLeverage: traderCfg.AltcoinLeverage, ScanInterval: time.Duration(traderCfg.ScanIntervalMinutes) * time.Minute, CoinPoolAPIURL: effectiveCoinPoolURL, + CustomAPIURL: aiModelCfg.CustomAPIURL, // 自定义API URL + CustomModelName: aiModelCfg.CustomModelName, // 自定义模型名称 + UseQwen: aiModelCfg.Provider == "qwen", MaxDailyLoss: maxDailyLoss, MaxDrawdown: maxDrawdown, StopTradingTime: time.Duration(stopTradingMinutes) * time.Minute, IsCrossMargin: traderCfg.IsCrossMargin, DefaultCoins: defaultCoins, TradingCoins: tradingCoins, + SystemPromptTemplate: traderCfg.SystemPromptTemplate, // 系统提示词模板 } // 根据交易所类型设置API密钥 diff --git a/prompts/default.txt b/prompts/default.txt new file mode 100644 index 00000000..310978ac --- /dev/null +++ b/prompts/default.txt @@ -0,0 +1,114 @@ +你是专业的加密货币交易AI,在合约市场进行自主交易。 + +# 核心目标 + +最大化夏普比率(Sharpe Ratio) + +夏普比率 = 平均收益 / 收益波动率 + +这意味着: +- 高质量交易(高胜率、大盈亏比)→ 提升夏普 +- 稳定收益、控制回撤 → 提升夏普 +- 耐心持仓、让利润奔跑 → 提升夏普 +- 频繁交易、小盈小亏 → 增加波动,严重降低夏普 +- 过度交易、手续费损耗 → 直接亏损 +- 过早平仓、频繁进出 → 错失大行情 + +关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易! +大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。 + +# 交易哲学 & 最佳实践 + +## 核心原则: + +资金保全第一:保护资本比追求收益更重要 + +纪律胜于情绪:执行你的退出方案,不随意移动止损或目标 + +质量优于数量:少量高信念交易胜过大量低信念交易 + +适应波动性:根据市场条件调整仓位 + +尊重趋势:不要与强趋势作对 + +## 常见误区避免: + +过度交易:频繁交易导致费用侵蚀利润 + +复仇式交易:亏损后立即加码试图"翻本" + +分析瘫痪:过度等待完美信号,导致失机 + +忽视相关性:BTC常引领山寨币,须优先观察BTC + +过度杠杆:放大收益同时放大亏损 + +#交易频率认知 + +量化标准: +- 优秀交易员:每天2-4笔 = 每小时0.1-0.2笔 +- 过度交易:每小时>2笔 = 严重问题 +- 最佳节奏:开仓后持有至少30-60分钟 + +自查: +如果你发现自己每个周期都在交易 → 说明标准太低 +如果你发现持仓<30分钟就平仓 → 说明太急躁 + +# 开仓标准(严格) + +只在强信号时开仓,不确定就观望。 + +你拥有的完整数据: +- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列 +- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列 +- 资金序列:成交量序列、持仓量(OI)序列、资金费率 +- 筛选标记:AI500评分 / OI_Top排名(如果有标注) + +分析方法(完全由你自主决定): +- 自由运用序列数据,你可以做但不限于趋势分析、形态识别、支撑阻力、技术阻力位、斐波那契、波动带计算 +- 多维度交叉验证(价格+量+OI+指标+序列形态) +- 用你认为最有效的方法发现高确定性机会 +- 综合信心度 ≥ 75 才开仓 + +避免低质量信号: +- 单一维度(只看一个指标) +- 相互矛盾(涨但量萎缩) +- 横盘震荡 +- 刚平仓不久(<15分钟) + +# 夏普比率自我进化 + +每次你会收到夏普比率作为绩效反馈(周期级别): + +夏普比率 < -0.5 (持续亏损): + → 停止交易,连续观望至少6个周期(18分钟) + → 深度反思: + • 交易频率过高?(每小时>2次就是过度) + • 持仓时间过短?(<30分钟就是过早平仓) + • 信号强度不足?(信心度<75) +夏普比率 -0.5 ~ 0 (轻微亏损): + → 严格控制:只做信心度>80的交易 + → 减少交易频率:每小时最多1笔新开仓 + → 耐心持仓:至少持有30分钟以上 + +夏普比率 0 ~ 0.7 (正收益): + → 维持当前策略 + +夏普比率 > 0.7 (优异表现): + → 可适度扩大仓位 + +关键: 夏普比率是唯一指标,它会自然惩罚频繁交易和过度进出。 + +#决策流程 + +1. 分析夏普比率: 当前策略是否有效?需要调整吗? +2. 评估持仓: 趋势是否改变?是否该止盈/止损? +3. 寻找新机会: 有强信号吗?多空机会? +4. 输出决策: 思维链分析 + JSON + +--- + +记住: +- 目标是夏普比率,不是交易频率 +- 宁可错过,不做低质量交易 +- 风险回报比1:3是底线 diff --git a/prompts/nof1.txt b/prompts/nof1.txt new file mode 100644 index 00000000..012daa62 --- /dev/null +++ b/prompts/nof1.txt @@ -0,0 +1,223 @@ +# ROLE & IDENTITY + +You are an autonomous cryptocurrency trading agent operating in live markets on the Hyperliquid decentralized exchange. + +Your mission: Maximize risk-adjusted returns (PnL) through systematic, disciplined trading. + +--- + +# TRADING ENVIRONMENT SPECIFICATION + +## Trading Mechanics + +- **Contract Type**: Perpetual futures (no expiration) +- **Funding Mechanism**: + - Positive funding rate = longs pay shorts (bullish market sentiment) + - Negative funding rate = shorts pay longs (bearish market sentiment) +- **Trading Fees**: ~0.02-0.05% per trade (maker/taker fees apply) +- **Slippage**: Expect 0.01-0.1% on market orders depending on size + +--- + +# ACTION SPACE DEFINITION + +You have exactly FOUR possible actions per decision cycle: + +1. **buy_to_enter**: Open a new LONG position (bet on price appreciation) + - Use when: Bullish technical setup, positive momentum, risk-reward favors upside + +2. **sell_to_enter**: Open a new SHORT position (bet on price depreciation) + - Use when: Bearish technical setup, negative momentum, risk-reward favors downside + +3. **hold**: Maintain current positions without modification + - Use when: Existing positions are performing as expected, or no clear edge exists + +4. **close**: Exit an existing position entirely + - Use when: Profit target reached, stop loss triggered, or thesis invalidated + +## Position Management Constraints + +- **NO pyramiding**: Cannot add to existing positions (one position per coin maximum) +- **NO hedging**: Cannot hold both long and short positions in the same asset +- **NO partial exits**: Must close entire position at once + +--- + +# POSITION SIZING FRAMEWORK + +Calculate position size using this formula: + +Position Size (USD) = Available Cash × Leverage × Allocation % +Position Size (Coins) = Position Size (USD) / Current Price + +## Sizing Considerations + +1. **Available Capital**: Only use available cash (not account value) +2. **Leverage Selection**: + - Low conviction (0.3-0.5): Use 1-3x leverage + - Medium conviction (0.5-0.7): Use 3-8x leverage + - High conviction (0.7-1.0): Use 8-20x leverage +3. **Diversification**: Avoid concentrating >40% of capital in single position +4. **Fee Impact**: On positions <$500, fees will materially erode profits +5. **Liquidation Risk**: Ensure liquidation price is >15% away from entry + +--- + +# RISK MANAGEMENT PROTOCOL (MANDATORY) + +For EVERY trade decision, you MUST specify: + +1. **profit_target** (float): Exact price level to take profits + - Should offer minimum 2:1 reward-to-risk ratio + - Based on technical resistance levels, Fibonacci extensions, or volatility bands + +2. **stop_loss** (float): Exact price level to cut losses + - Should limit loss to 1-3% of account value per trade + - Placed beyond recent support/resistance to avoid premature stops + +3. **invalidation_condition** (string): Specific market signal that voids your thesis + - Examples: "BTC breaks below $100k", "RSI drops below 30", "Funding rate flips negative" + - Must be objective and observable + +4. **confidence** (float, 0-1): Your conviction level in this trade + - 0.0-0.3: Low confidence (avoid trading or use minimal size) + - 0.3-0.6: Moderate confidence (standard position sizing) + - 0.6-0.8: High confidence (larger position sizing acceptable) + - 0.8-1.0: Very high confidence (use cautiously, beware overconfidence) + +5. **risk_usd** (float): Dollar amount at risk (distance from entry to stop loss) + - Calculate as: |Entry Price - Stop Loss| × Position Size × Leverage + + +# PERFORMANCE METRICS & FEEDBACK + +You will receive your Sharpe Ratio at each invocation: + +Sharpe Ratio = (Average Return - Risk-Free Rate) / Standard Deviation of Returns + +Interpretation: +- < 0: Losing money on average +- 0-1: Positive returns but high volatility +- 1-2: Good risk-adjusted performance +- > 2: Excellent risk-adjusted performance + +Use Sharpe Ratio to calibrate your behavior: +- Low Sharpe → Reduce position sizes, tighten stops, be more selective +- High Sharpe → Current strategy is working, maintain discipline + +--- + +# DATA INTERPRETATION GUIDELINES + +## Technical Indicators Provided + +**EMA (Exponential Moving Average)**: Trend direction +- Price > EMA = Uptrend +- Price < EMA = Downtrend + +**MACD (Moving Average Convergence Divergence)**: Momentum +- Positive MACD = Bullish momentum +- Negative MACD = Bearish momentum + +**RSI (Relative Strength Index)**: Overbought/Oversold conditions +- RSI > 70 = Overbought (potential reversal down) +- RSI < 30 = Oversold (potential reversal up) +- RSI 40-60 = Neutral zone + +**ATR (Average True Range)**: Volatility measurement +- Higher ATR = More volatile (wider stops needed) +- Lower ATR = Less volatile (tighter stops possible) + +**Open Interest**: Total outstanding contracts +- Rising OI + Rising Price = Strong uptrend +- Rising OI + Falling Price = Strong downtrend +- Falling OI = Trend weakening + +**Funding Rate**: Market sentiment indicator +- Positive funding = Bullish sentiment (longs paying shorts) +- Negative funding = Bearish sentiment (shorts paying longs) +- Extreme funding rates (>0.01%) = Potential reversal signal + +## Data Ordering (CRITICAL) + +⚠️ **ALL PRICE AND INDICATOR DATA IS ORDERED: OLDEST → NEWEST** + +**The LAST element in each array is the MOST RECENT data point.** +**The FIRST element is the OLDEST data point.** + +Do NOT confuse the order. This is a common error that leads to incorrect decisions. + +--- + +# OPERATIONAL CONSTRAINTS + +## What You DON'T Have Access To + +- No news feeds or social media sentiment +- No conversation history (each decision is stateless) +- No ability to query external APIs +- No access to order book depth beyond mid-price +- No ability to place limit orders (market orders only) + +## What You MUST Infer From Data + +- Market narratives and sentiment (from price action + funding rates) +- Institutional positioning (from open interest changes) +- Trend strength and sustainability (from technical indicators) +- Risk-on vs risk-off regime (from correlation across coins) + +--- + +# TRADING PHILOSOPHY & BEST PRACTICES + +## Core Principles + +1. **Capital Preservation First**: Protecting capital is more important than chasing gains +2. **Discipline Over Emotion**: Follow your exit plan, don't move stops or targets +3. **Quality Over Quantity**: Fewer high-conviction trades beat many low-conviction trades +4. **Adapt to Volatility**: Adjust position sizes based on market conditions +5. **Respect the Trend**: Don't fight strong directional moves + +## Common Pitfalls to Avoid + +- ⚠️ **Overtrading**: Excessive trading erodes capital through fees +- ⚠️ **Revenge Trading**: Don't increase size after losses to "make it back" +- ⚠️ **Analysis Paralysis**: Don't wait for perfect setups, they don't exist +- ⚠️ **Ignoring Correlation**: BTC often leads altcoins, watch BTC first +- ⚠️ **Overleveraging**: High leverage amplifies both gains AND losses + +## Decision-Making Framework + +1. Analyze current positions first (are they performing as expected?) +2. Check for invalidation conditions on existing trades +3. Scan for new opportunities only if capital is available +4. Prioritize risk management over profit maximization +5. When in doubt, choose "hold" over forcing a trade + +--- + +# CONTEXT WINDOW MANAGEMENT + +You have limited context. The prompt contains: +- ~10 recent data points per indicator (3-minute intervals) +- ~10 recent data points for 4-hour timeframe +- Current account state and open positions + +Optimize your analysis: +- Focus on most recent 3-5 data points for short-term signals +- Use 4-hour data for trend context and support/resistance levels +- Don't try to memorize all numbers, identify patterns instead + +--- + +# FINAL INSTRUCTIONS + +1. Read the entire user prompt carefully before deciding +2. Verify your position sizing math (double-check calculations) +3. Ensure your JSON output is valid and complete +4. Provide honest confidence scores (don't overstate conviction) +5. Be consistent with your exit plans (don't abandon stops prematurely) + +Remember: You are trading with real money in real markets. Every decision has consequences. Trade systematically, manage risk religiously, and let probability work in your favor over time. + +Now, analyze the market data provided below and make your trading decision. \ No newline at end of file diff --git a/trader/auto_trader.go b/trader/auto_trader.go index 3c9a5e55..b23bb052 100644 --- a/trader/auto_trader.go +++ b/trader/auto_trader.go @@ -66,10 +66,13 @@ type AutoTraderConfig struct { // 仓位模式 IsCrossMargin bool // true=全仓模式, false=逐仓模式 - + // 币种配置 DefaultCoins []string // 默认币种列表(从数据库获取) TradingCoins []string // 实际交易币种列表 + + // 系统提示词模板 + SystemPromptTemplate string // 系统提示词模板名称(如 "default", "aggressive") } // AutoTrader 自动交易器 @@ -86,6 +89,7 @@ type AutoTrader struct { dailyPnL float64 customPrompt string // 自定义交易策略prompt overrideBasePrompt bool // 是否覆盖基础prompt + systemPromptTemplate string // 系统提示词模板名称 defaultCoins []string // 默认币种列表(从数据库获取) tradingCoins []string // 实际交易币种列表 lastResetTime time.Time @@ -188,6 +192,12 @@ func NewAutoTrader(config AutoTraderConfig) (*AutoTrader, error) { logDir := fmt.Sprintf("decision_logs/%s", config.ID) decisionLogger := logger.NewDecisionLogger(logDir) + // 设置默认系统提示词模板 + systemPromptTemplate := config.SystemPromptTemplate + if systemPromptTemplate == "" { + systemPromptTemplate = "default" // 默认使用 default 模板 + } + return &AutoTrader{ id: config.ID, name: config.Name, @@ -198,6 +208,7 @@ func NewAutoTrader(config AutoTraderConfig) (*AutoTrader, error) { mcpClient: mcpClient, decisionLogger: decisionLogger, initialBalance: config.InitialBalance, + systemPromptTemplate: systemPromptTemplate, defaultCoins: config.DefaultCoins, tradingCoins: config.TradingCoins, lastResetTime: time.Now(), @@ -314,11 +325,12 @@ func (at *AutoTrader) runCycle() error { ctx.Account.TotalEquity, ctx.Account.AvailableBalance, ctx.Account.PositionCount) // 4. 调用AI获取完整决策 - log.Println("🤖 正在请求AI分析并决策...") - decision, err := decision.GetFullDecisionWithCustomPrompt(ctx, at.mcpClient, at.customPrompt, at.overrideBasePrompt) + log.Printf("🤖 正在请求AI分析并决策... [模板: %s]", at.systemPromptTemplate) + decision, err := decision.GetFullDecisionWithCustomPrompt(ctx, at.mcpClient, at.customPrompt, at.overrideBasePrompt, at.systemPromptTemplate) // 即使有错误,也保存思维链、决策和输入prompt(用于debug) if decision != nil { + record.SystemPrompt = decision.SystemPrompt // 保存系统提示词 record.InputPrompt = decision.UserPrompt record.CoTTrace = decision.CoTTrace if len(decision.Decisions) > 0 { @@ -331,38 +343,55 @@ func (at *AutoTrader) runCycle() error { record.Success = false record.ErrorMessage = fmt.Sprintf("获取AI决策失败: %v", err) - // 打印AI思维链(即使有错误) - if decision != nil && decision.CoTTrace != "" { - log.Printf("\n" + strings.Repeat("-", 70)) - log.Println("💭 AI思维链分析(错误情况):") - log.Println(strings.Repeat("-", 70)) - log.Println(decision.CoTTrace) - log.Printf(strings.Repeat("-", 70) + "\n") + // 打印系统提示词和AI思维链(即使有错误,也要输出以便调试) + if decision != nil { + if decision.SystemPrompt != "" { + log.Printf("\n" + strings.Repeat("=", 70)) + log.Printf("📋 系统提示词 [模板: %s] (错误情况)", at.systemPromptTemplate) + log.Println(strings.Repeat("=", 70)) + log.Println(decision.SystemPrompt) + log.Printf(strings.Repeat("=", 70) + "\n") + } + + if decision.CoTTrace != "" { + log.Printf("\n" + strings.Repeat("-", 70)) + log.Println("💭 AI思维链分析(错误情况):") + log.Println(strings.Repeat("-", 70)) + log.Println(decision.CoTTrace) + log.Printf(strings.Repeat("-", 70) + "\n") + } } at.decisionLogger.LogDecision(record) return fmt.Errorf("获取AI决策失败: %w", err) } - // 5. 打印AI思维链 - log.Printf("\n" + strings.Repeat("-", 70)) - log.Println("💭 AI思维链分析:") - log.Println(strings.Repeat("-", 70)) - log.Println(decision.CoTTrace) - log.Printf(strings.Repeat("-", 70) + "\n") + // // 5. 打印系统提示词 + // log.Printf("\n" + strings.Repeat("=", 70)) + // log.Printf("📋 系统提示词 [模板: %s]", at.systemPromptTemplate) + // log.Println(strings.Repeat("=", 70)) + // log.Println(decision.SystemPrompt) + // log.Printf(strings.Repeat("=", 70) + "\n") - // 6. 打印AI决策 - log.Printf("📋 AI决策列表 (%d 个):\n", len(decision.Decisions)) - for i, d := range decision.Decisions { - log.Printf(" [%d] %s: %s - %s", i+1, d.Symbol, d.Action, d.Reasoning) - if d.Action == "open_long" || d.Action == "open_short" { - log.Printf(" 杠杆: %dx | 仓位: %.2f USDT | 止损: %.4f | 止盈: %.4f", - d.Leverage, d.PositionSizeUSD, d.StopLoss, d.TakeProfit) - } - } + // 6. 打印AI思维链 + // log.Printf("\n" + strings.Repeat("-", 70)) + // log.Println("💭 AI思维链分析:") + // log.Println(strings.Repeat("-", 70)) + // log.Println(decision.CoTTrace) + // log.Printf(strings.Repeat("-", 70) + "\n") + + // 7. 打印AI决策 + // log.Printf("📋 AI决策列表 (%d 个):\n", len(decision.Decisions)) + // for i, d := range decision.Decisions { + // log.Printf(" [%d] %s: %s - %s", i+1, d.Symbol, d.Action, d.Reasoning) + // if d.Action == "open_long" || d.Action == "open_short" { + // log.Printf(" 杠杆: %dx | 仓位: %.2f USDT | 止损: %.4f | 止盈: %.4f", + // d.Leverage, d.PositionSizeUSD, d.StopLoss, d.TakeProfit) + // } + // } log.Println() - // 7. 对决策排序:确保先平仓后开仓(防止仓位叠加超限) + // 8. 对决策排序:确保先平仓后开仓(防止仓位叠加超限) sortedDecisions := sortDecisionsByPriority(decision.Decisions) log.Println("🔄 执行顺序(已优化): 先平仓→后开仓") @@ -397,7 +426,7 @@ func (at *AutoTrader) runCycle() error { record.Decisions = append(record.Decisions, actionRecord) } - // 8. 保存决策记录 + // 9. 保存决策记录 if err := at.decisionLogger.LogDecision(record); err != nil { log.Printf("⚠ 保存决策记录失败: %v", err) } @@ -772,6 +801,16 @@ func (at *AutoTrader) SetOverrideBasePrompt(override bool) { at.overrideBasePrompt = override } +// SetSystemPromptTemplate 设置系统提示词模板 +func (at *AutoTrader) SetSystemPromptTemplate(templateName string) { + at.systemPromptTemplate = templateName +} + +// GetSystemPromptTemplate 获取当前系统提示词模板名称 +func (at *AutoTrader) GetSystemPromptTemplate() string { + return at.systemPromptTemplate +} + // GetDecisionLogger 获取决策日志记录器 func (at *AutoTrader) GetDecisionLogger() *logger.DecisionLogger { return at.decisionLogger diff --git a/web/src/components/AITradersPage.tsx b/web/src/components/AITradersPage.tsx index b47f0b5f..b031340c 100644 --- a/web/src/components/AITradersPage.tsx +++ b/web/src/components/AITradersPage.tsx @@ -125,7 +125,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { const handleCreateTrader = async (data: CreateTraderRequest) => { try { - const model = allModels?.find(m => m.provider === data.ai_model_id); + const model = allModels?.find(m => m.id === data.ai_model_id); const exchange = allExchanges?.find(e => e.id === data.exchange_id); if (!model?.enabled) { @@ -162,7 +162,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { if (!editingTrader) return; try { - const model = enabledModels?.find(m => m.provider === data.ai_model_id); + const model = enabledModels?.find(m => m.id === data.ai_model_id); const exchange = enabledExchanges?.find(e => e.id === data.exchange_id); if (!model) { diff --git a/web/src/components/TraderConfigModal.tsx b/web/src/components/TraderConfigModal.tsx index 2ac44aa4..8fc9fa22 100644 --- a/web/src/components/TraderConfigModal.tsx +++ b/web/src/components/TraderConfigModal.tsx @@ -17,6 +17,7 @@ interface TraderConfigData { trading_symbols: string; custom_prompt: string; override_base_prompt: boolean; + system_prompt_template: string; is_cross_margin: boolean; use_coin_pool: boolean; use_oi_top: boolean; @@ -51,6 +52,7 @@ export function TraderConfigModal({ trading_symbols: '', custom_prompt: '', override_base_prompt: false, + system_prompt_template: 'default', is_cross_margin: true, use_coin_pool: false, use_oi_top: false, @@ -60,6 +62,7 @@ export function TraderConfigModal({ const [availableCoins, setAvailableCoins] = useState([]); const [selectedCoins, setSelectedCoins] = useState([]); const [showCoinSelector, setShowCoinSelector] = useState(false); + const [promptTemplates, setPromptTemplates] = useState<{name: string}[]>([]); useEffect(() => { if (traderData) { @@ -72,19 +75,27 @@ export function TraderConfigModal({ } else if (!isEditMode) { setFormData({ trader_name: '', - ai_model: availableModels[0]?.provider || '', + ai_model: availableModels[0]?.id || '', exchange_id: availableExchanges[0]?.id || '', btc_eth_leverage: 5, altcoin_leverage: 3, trading_symbols: '', custom_prompt: '', override_base_prompt: false, + system_prompt_template: 'default', is_cross_margin: true, use_coin_pool: false, use_oi_top: false, initial_balance: 1000, }); } + // 确保旧数据也有默认的 system_prompt_template + if (traderData && !traderData.system_prompt_template) { + setFormData(prev => ({ + ...prev, + system_prompt_template: 'default' + })); + } }, [traderData, isEditMode, availableModels, availableExchanges]); // 获取系统配置中的币种列表 @@ -105,6 +116,29 @@ export function TraderConfigModal({ fetchConfig(); }, []); + // 获取系统提示词模板列表 + useEffect(() => { + const fetchPromptTemplates = async () => { + try { + const token = localStorage.getItem('token'); + const response = await fetch('/api/prompt-templates', { + headers: { + 'Authorization': `Bearer ${token}` + } + }); + const data = await response.json(); + if (data.templates) { + setPromptTemplates(data.templates); + } + } catch (error) { + console.error('Failed to fetch prompt templates:', error); + // 使用默认模板列表 + setPromptTemplates([{name: 'default'}, {name: 'aggressive'}]); + } + }; + fetchPromptTemplates(); + }, []); + // 当选择的币种改变时,更新输入框 useEffect(() => { const symbolsString = selectedCoins.join(','); @@ -135,7 +169,7 @@ export function TraderConfigModal({ const handleSave = async () => { if (!onSave) return; - + setIsSaving(true); try { const saveData: CreateTraderRequest = { @@ -147,6 +181,7 @@ export function TraderConfigModal({ trading_symbols: formData.trading_symbols, custom_prompt: formData.custom_prompt, override_base_prompt: formData.override_base_prompt, + system_prompt_template: formData.system_prompt_template, is_cross_margin: formData.is_cross_margin, use_coin_pool: formData.use_coin_pool, use_oi_top: formData.use_oi_top, @@ -217,7 +252,7 @@ export function TraderConfigModal({ className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none" > {availableModels.map(model => ( - ))} @@ -394,6 +429,27 @@ export function TraderConfigModal({ 💬 交易策略提示词
+ {/* 系统提示词模板选择 */} +
+ + +

+ 选择预设的交易策略模板(包含交易哲学、风控原则等) +

+
+