Skip to content

Commit 0745fdf

Browse files
committed
feat: Add scan_interval_minutes configuration support (PR NoFxAiOS#338)
- Allow users to customize AI decision scan interval (1-60 minutes) - Default 3 minutes, recommended range 3-10 minutes - Support both high-frequency and low-frequency trading strategies - Improve trading flexibility and API call efficiency - Merge with existing actual balance query functionality
2 parents cd479d4 + df83a87 commit 0745fdf

File tree

5 files changed

+55
-16
lines changed

5 files changed

+55
-16
lines changed

api/server.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ type CreateTraderRequest struct {
210210
AIModelID string `json:"ai_model_id" binding:"required"`
211211
ExchangeID string `json:"exchange_id" binding:"required"`
212212
InitialBalance float64 `json:"initial_balance"`
213+
ScanIntervalMinutes int `json:"scan_interval_minutes"`
213214
BTCETHLeverage int `json:"btc_eth_leverage"`
214215
AltcoinLeverage int `json:"altcoin_leverage"`
215216
TradingSymbols string `json:"trading_symbols"`
@@ -332,6 +333,12 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
332333
systemPromptTemplate = req.SystemPromptTemplate
333334
}
334335

336+
// 设置扫描间隔默认值
337+
scanIntervalMinutes := req.ScanIntervalMinutes
338+
if scanIntervalMinutes <= 0 {
339+
scanIntervalMinutes = 3 // 默认3分钟
340+
}
341+
335342
// ✨ 查询交易所实际余额,覆盖用户输入
336343
actualBalance := req.InitialBalance // 默认使用用户输入
337344
exchanges, err := s.database.GetExchanges(userID)
@@ -416,7 +423,7 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
416423
OverrideBasePrompt: req.OverrideBasePrompt,
417424
SystemPromptTemplate: systemPromptTemplate,
418425
IsCrossMargin: isCrossMargin,
419-
ScanIntervalMinutes: 3, // 默认3分钟
426+
ScanIntervalMinutes: scanIntervalMinutes,
420427
IsRunning: false,
421428
}
422429

@@ -456,6 +463,7 @@ type UpdateTraderRequest struct {
456463
CustomPrompt string `json:"custom_prompt"`
457464
OverrideBasePrompt bool `json:"override_base_prompt"`
458465
IsCrossMargin *bool `json:"is_cross_margin"`
466+
ScanIntervalMinutes int `json:"scan_interval_minutes"`
459467
}
460468

461469
// handleUpdateTrader 更新交易员配置
@@ -505,6 +513,12 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
505513
altcoinLeverage = existingTrader.AltcoinLeverage // 保持原值
506514
}
507515

516+
// 设置扫描间隔,允许更新
517+
scanIntervalMinutes := req.ScanIntervalMinutes
518+
if scanIntervalMinutes <= 0 {
519+
scanIntervalMinutes = existingTrader.ScanIntervalMinutes // 保持原值
520+
}
521+
508522
// 更新交易员配置
509523
trader := &config.TraderRecord{
510524
ID: traderID,
@@ -513,14 +527,14 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
513527
AIModelID: req.AIModelID,
514528
ExchangeID: req.ExchangeID,
515529
InitialBalance: req.InitialBalance,
516-
BTCETHLeverage: btcEthLeverage,
517530
AltcoinLeverage: altcoinLeverage,
518-
TradingSymbols: req.TradingSymbols,
519-
CustomPrompt: req.CustomPrompt,
520-
OverrideBasePrompt: req.OverrideBasePrompt,
521-
IsCrossMargin: isCrossMargin,
522-
ScanIntervalMinutes: existingTrader.ScanIntervalMinutes, // 保持原值
523-
IsRunning: existingTrader.IsRunning, // 保持原值
531+
TradingSymbols: req.TradingSymbols,
532+
CustomPrompt: req.CustomPrompt,
533+
OverrideBasePrompt: req.OverrideBasePrompt,
534+
SystemPromptTemplate: existingTrader.SystemPromptTemplate, // 保持原值
535+
IsCrossMargin: isCrossMargin,
536+
ScanIntervalMinutes: scanIntervalMinutes,
537+
IsRunning: existingTrader.IsRunning, // 保持原值
524538
}
525539

526540
// 更新数据库
@@ -868,12 +882,12 @@ func (s *Server) handleGetTraderConfig(c *gin.Context) {
868882
"ai_model": traderConfig.AIModelID, // 使用完整 ID
869883
"exchange_id": traderConfig.ExchangeID,
870884
"initial_balance": traderConfig.InitialBalance,
885+
"scan_interval_minutes": traderConfig.ScanIntervalMinutes,
871886
"btc_eth_leverage": traderConfig.BTCETHLeverage,
872887
"altcoin_leverage": traderConfig.AltcoinLeverage,
873888
"trading_symbols": traderConfig.TradingSymbols,
874889
"custom_prompt": traderConfig.CustomPrompt,
875890
"override_base_prompt": traderConfig.OverrideBasePrompt,
876-
"system_prompt_template": traderConfig.SystemPromptTemplate, // 添加此字段
877891
"is_cross_margin": traderConfig.IsCrossMargin,
878892
"use_coin_pool": traderConfig.UseCoinPool,
879893
"use_oi_top": traderConfig.UseOITop,

web/src/components/AITradersPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
207207
ai_model_id: ai_model_id, // 使用修正后的值
208208
exchange_id: exchange_id, // 使用修正后的值
209209
initial_balance: data.initial_balance,
210+
scan_interval_minutes: data.scan_interval_minutes,
210211
btc_eth_leverage: data.btc_eth_leverage,
211212
altcoin_leverage: data.altcoin_leverage,
212213
trading_symbols: data.trading_symbols,

web/src/components/TraderConfigModal.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface TraderConfigData {
2626
use_coin_pool: boolean;
2727
use_oi_top: boolean;
2828
initial_balance: number;
29+
scan_interval_minutes: number;
2930
}
3031

3132
interface TraderConfigModalProps {
@@ -61,6 +62,7 @@ export function TraderConfigModal({
6162
use_coin_pool: false,
6263
use_oi_top: false,
6364
initial_balance: 1000,
65+
scan_interval_minutes: 3,
6466
});
6567
const [isSaving, setIsSaving] = useState(false);
6668
const [availableCoins, setAvailableCoins] = useState<string[]>([]);
@@ -91,6 +93,7 @@ export function TraderConfigModal({
9193
use_coin_pool: false,
9294
use_oi_top: false,
9395
initial_balance: 1000,
96+
scan_interval_minutes: 3,
9497
});
9598
}
9699
// 确保旧数据也有默认的 system_prompt_template
@@ -185,6 +188,7 @@ export function TraderConfigModal({
185188
use_coin_pool: formData.use_coin_pool,
186189
use_oi_top: formData.use_oi_top,
187190
initial_balance: formData.initial_balance,
191+
scan_interval_minutes: formData.scan_interval_minutes,
188192
};
189193
await onSave(saveData);
190194
onClose();
@@ -323,7 +327,25 @@ export function TraderConfigModal({
323327
</div>
324328
</div>
325329

326-
{/* 第二行:杠杆设置 */}
330+
{/* 第二行:AI 扫描决策间隔 */}
331+
<div className="grid grid-cols-2 gap-4">
332+
<div>
333+
<label className="text-sm text-[#EAECEF] block mb-2">AI 扫描决策间隔 (分钟)</label>
334+
<input
335+
type="number"
336+
value={formData.scan_interval_minutes}
337+
onChange={(e) => handleInputChange('scan_interval_minutes', Number(e.target.value))}
338+
className="w-full px-3 py-2 bg-[#0B0E11] border border-[#2B3139] rounded text-[#EAECEF] focus:border-[#F0B90B] focus:outline-none"
339+
min="1"
340+
max="60"
341+
step="1"
342+
/>
343+
<p className="text-xs text-gray-500 mt-1">建议: 3-10分钟</p>
344+
</div>
345+
<div></div>
346+
</div>
347+
348+
{/* 第三行:杠杆设置 */}
327349
<div className="grid grid-cols-2 gap-4">
328350
<div>
329351
<label className="text-sm text-[#EAECEF] block mb-2">BTC/ETH 杠杆</label>

web/src/components/landing/CommunitySection.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { motion } from 'framer-motion'
22
import AnimatedSection from './AnimatedSection'
33

44
interface CardProps {
5-
quote: string
6-
authorName: string
7-
handle: string
8-
avatarUrl: string
9-
tweetUrl: string
10-
delay: number
5+
quote: string;
6+
authorName: string;
7+
handle: string;
8+
avatarUrl: string;
9+
tweetUrl: string;
10+
delay: number;
1111
}
1212

1313
function TestimonialCard({ quote, authorName, delay }: CardProps) {

web/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export interface CreateTraderRequest {
125125
ai_model_id: string;
126126
exchange_id: string;
127127
initial_balance: number;
128+
scan_interval_minutes?: number;
128129
btc_eth_leverage?: number;
129130
altcoin_leverage?: number;
130131
trading_symbols?: string;
@@ -199,5 +200,6 @@ export interface TraderConfigData {
199200
use_coin_pool: boolean;
200201
use_oi_top: boolean;
201202
initial_balance: number;
203+
scan_interval_minutes: number;
202204
is_running: boolean;
203205
}

0 commit comments

Comments
 (0)