Skip to content

Commit df83a87

Browse files
authored
Merge pull request #338 from xqliu/feat/add-scan-interval-config-v2
feat: 添加 AI 扫描决策间隔配置支持
2 parents 0a94100 + 8ad85a4 commit df83a87

File tree

5 files changed

+93
-43
lines changed

5 files changed

+93
-43
lines changed

api/server.go

Lines changed: 56 additions & 40 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
trader := &config.TraderRecord{
337344
ID: traderID,
@@ -349,7 +356,7 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
349356
OverrideBasePrompt: req.OverrideBasePrompt,
350357
SystemPromptTemplate: systemPromptTemplate,
351358
IsCrossMargin: isCrossMargin,
352-
ScanIntervalMinutes: 3, // 默认3分钟
359+
ScanIntervalMinutes: scanIntervalMinutes,
353360
IsRunning: false,
354361
}
355362

@@ -379,16 +386,17 @@ func (s *Server) handleCreateTrader(c *gin.Context) {
379386

380387
// UpdateTraderRequest 更新交易员请求
381388
type UpdateTraderRequest struct {
382-
Name string `json:"name" binding:"required"`
383-
AIModelID string `json:"ai_model_id" binding:"required"`
384-
ExchangeID string `json:"exchange_id" binding:"required"`
385-
InitialBalance float64 `json:"initial_balance"`
386-
BTCETHLeverage int `json:"btc_eth_leverage"`
387-
AltcoinLeverage int `json:"altcoin_leverage"`
388-
TradingSymbols string `json:"trading_symbols"`
389-
CustomPrompt string `json:"custom_prompt"`
390-
OverrideBasePrompt bool `json:"override_base_prompt"`
391-
IsCrossMargin *bool `json:"is_cross_margin"`
389+
Name string `json:"name" binding:"required"`
390+
AIModelID string `json:"ai_model_id" binding:"required"`
391+
ExchangeID string `json:"exchange_id" binding:"required"`
392+
InitialBalance float64 `json:"initial_balance"`
393+
ScanIntervalMinutes int `json:"scan_interval_minutes"`
394+
BTCETHLeverage int `json:"btc_eth_leverage"`
395+
AltcoinLeverage int `json:"altcoin_leverage"`
396+
TradingSymbols string `json:"trading_symbols"`
397+
CustomPrompt string `json:"custom_prompt"`
398+
OverrideBasePrompt bool `json:"override_base_prompt"`
399+
IsCrossMargin *bool `json:"is_cross_margin"`
392400
}
393401

394402
// handleUpdateTrader 更新交易员配置
@@ -437,23 +445,30 @@ func (s *Server) handleUpdateTrader(c *gin.Context) {
437445
if altcoinLeverage <= 0 {
438446
altcoinLeverage = existingTrader.AltcoinLeverage // 保持原值
439447
}
440-
448+
449+
// 设置扫描间隔,允许更新
450+
scanIntervalMinutes := req.ScanIntervalMinutes
451+
if scanIntervalMinutes <= 0 {
452+
scanIntervalMinutes = existingTrader.ScanIntervalMinutes // 保持原值
453+
}
454+
441455
// 更新交易员配置
442456
trader := &config.TraderRecord{
443-
ID: traderID,
444-
UserID: userID,
445-
Name: req.Name,
446-
AIModelID: req.AIModelID,
447-
ExchangeID: req.ExchangeID,
448-
InitialBalance: req.InitialBalance,
449-
BTCETHLeverage: btcEthLeverage,
450-
AltcoinLeverage: altcoinLeverage,
451-
TradingSymbols: req.TradingSymbols,
452-
CustomPrompt: req.CustomPrompt,
453-
OverrideBasePrompt: req.OverrideBasePrompt,
454-
IsCrossMargin: isCrossMargin,
455-
ScanIntervalMinutes: existingTrader.ScanIntervalMinutes, // 保持原值
456-
IsRunning: existingTrader.IsRunning, // 保持原值
457+
ID: traderID,
458+
UserID: userID,
459+
Name: req.Name,
460+
AIModelID: req.AIModelID,
461+
ExchangeID: req.ExchangeID,
462+
InitialBalance: req.InitialBalance,
463+
BTCETHLeverage: btcEthLeverage,
464+
AltcoinLeverage: altcoinLeverage,
465+
TradingSymbols: req.TradingSymbols,
466+
CustomPrompt: req.CustomPrompt,
467+
OverrideBasePrompt: req.OverrideBasePrompt,
468+
SystemPromptTemplate: existingTrader.SystemPromptTemplate, // 保持原值
469+
IsCrossMargin: isCrossMargin,
470+
ScanIntervalMinutes: scanIntervalMinutes,
471+
IsRunning: existingTrader.IsRunning, // 保持原值
457472
}
458473

459474
// 更新数据库
@@ -805,20 +820,21 @@ func (s *Server) handleGetTraderConfig(c *gin.Context) {
805820
aiModelID := traderConfig.AIModelID
806821

807822
result := map[string]interface{}{
808-
"trader_id": traderConfig.ID,
809-
"trader_name": traderConfig.Name,
810-
"ai_model": aiModelID,
811-
"exchange_id": traderConfig.ExchangeID,
812-
"initial_balance": traderConfig.InitialBalance,
813-
"btc_eth_leverage": traderConfig.BTCETHLeverage,
814-
"altcoin_leverage": traderConfig.AltcoinLeverage,
815-
"trading_symbols": traderConfig.TradingSymbols,
816-
"custom_prompt": traderConfig.CustomPrompt,
817-
"override_base_prompt": traderConfig.OverrideBasePrompt,
818-
"is_cross_margin": traderConfig.IsCrossMargin,
819-
"use_coin_pool": traderConfig.UseCoinPool,
820-
"use_oi_top": traderConfig.UseOITop,
821-
"is_running": isRunning,
823+
"trader_id": traderConfig.ID,
824+
"trader_name": traderConfig.Name,
825+
"ai_model": aiModelID,
826+
"exchange_id": traderConfig.ExchangeID,
827+
"initial_balance": traderConfig.InitialBalance,
828+
"scan_interval_minutes": traderConfig.ScanIntervalMinutes,
829+
"btc_eth_leverage": traderConfig.BTCETHLeverage,
830+
"altcoin_leverage": traderConfig.AltcoinLeverage,
831+
"trading_symbols": traderConfig.TradingSymbols,
832+
"custom_prompt": traderConfig.CustomPrompt,
833+
"override_base_prompt": traderConfig.OverrideBasePrompt,
834+
"is_cross_margin": traderConfig.IsCrossMargin,
835+
"use_coin_pool": traderConfig.UseCoinPool,
836+
"use_oi_top": traderConfig.UseOITop,
837+
"is_running": isRunning,
822838
}
823839

824840
c.JSON(http.StatusOK, result)

web/src/components/AITradersPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
183183
ai_model_id: data.ai_model_id,
184184
exchange_id: data.exchange_id,
185185
initial_balance: data.initial_balance,
186+
scan_interval_minutes: data.scan_interval_minutes,
186187
btc_eth_leverage: data.btc_eth_leverage,
187188
altcoin_leverage: data.altcoin_leverage,
188189
trading_symbols: data.trading_symbols,

web/src/components/TraderConfigModal.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface TraderConfigData {
2222
use_coin_pool: boolean;
2323
use_oi_top: boolean;
2424
initial_balance: number;
25+
scan_interval_minutes: number;
2526
}
2627

2728
interface TraderConfigModalProps {
@@ -57,6 +58,7 @@ export function TraderConfigModal({
5758
use_coin_pool: false,
5859
use_oi_top: false,
5960
initial_balance: 1000,
61+
scan_interval_minutes: 3,
6062
});
6163
const [isSaving, setIsSaving] = useState(false);
6264
const [availableCoins, setAvailableCoins] = useState<string[]>([]);
@@ -87,6 +89,7 @@ export function TraderConfigModal({
8789
use_coin_pool: false,
8890
use_oi_top: false,
8991
initial_balance: 1000,
92+
scan_interval_minutes: 3,
9093
});
9194
}
9295
// 确保旧数据也有默认的 system_prompt_template
@@ -181,6 +184,7 @@ export function TraderConfigModal({
181184
use_coin_pool: formData.use_coin_pool,
182185
use_oi_top: formData.use_oi_top,
183186
initial_balance: formData.initial_balance,
187+
scan_interval_minutes: formData.scan_interval_minutes,
184188
};
185189
await onSave(saveData);
186190
onClose();
@@ -319,7 +323,25 @@ export function TraderConfigModal({
319323
</div>
320324
</div>
321325

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

web/src/components/landing/CommunitySection.tsx

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

4-
function TestimonialCard({ quote, author, delay }: any) {
4+
interface CardProps {
5+
quote: string;
6+
authorName: string;
7+
handle: string;
8+
avatarUrl: string;
9+
tweetUrl: string;
10+
delay: number;
11+
}
12+
13+
function TestimonialCard({ quote, authorName, delay }: CardProps) {
514
return (
615
<motion.div
716
className='p-6 rounded-xl'
@@ -18,7 +27,7 @@ function TestimonialCard({ quote, author, delay }: any) {
1827
<div className='flex items-center gap-2'>
1928
<div className='w-8 h-8 rounded-full' style={{ background: 'var(--binance-yellow)' }} />
2029
<span className='text-sm font-semibold' style={{ color: 'var(--text-secondary)' }}>
21-
{author}
30+
{authorName}
2231
</span>
2332
</div>
2433
</motion.div>

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;
@@ -198,5 +199,6 @@ export interface TraderConfigData {
198199
use_coin_pool: boolean;
199200
use_oi_top: boolean;
200201
initial_balance: number;
202+
scan_interval_minutes: number;
201203
is_running: boolean;
202204
}

0 commit comments

Comments
 (0)