-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbot_group_manager.go
More file actions
133 lines (118 loc) · 3.25 KB
/
bot_group_manager.go
File metadata and controls
133 lines (118 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"context"
"sync"
"quantmesh/config"
"quantmesh/event"
"quantmesh/logger"
"quantmesh/strategy"
"quantmesh/web"
)
// BotGroupManager Bot 組生命週期管理
// 負責啟停 Group 內所有 Bot、聚合狀態、對沖協調
type BotGroupManager struct {
mu sync.RWMutex
coordinators map[string]*strategy.HedgeCoordinator
eventBus *event.EventBus
startBotFn func(ctx context.Context, cfg config.BotConfig) error
stopBotFn func(botID string) error
}
// NewBotGroupManager 創建 Bot 組管理器
func NewBotGroupManager(eventBus *event.EventBus, startBotFn func(context.Context, config.BotConfig) error, stopBotFn func(string) error) *BotGroupManager {
return &BotGroupManager{
coordinators: make(map[string]*strategy.HedgeCoordinator),
eventBus: eventBus,
startBotFn: startBotFn,
stopBotFn: stopBotFn,
}
}
// StartGroup 啟動 Group 內所有 Bot 及對沖協調器
func (m *BotGroupManager) StartGroup(ctx context.Context, group config.BotGroup) error {
m.mu.Lock()
defer m.mu.Unlock()
cfg, err := web.GetLatestConfig()
if err != nil || cfg == nil {
return err
}
// 啟動組內每個 Bot
for _, botID := range group.BotIDs {
var botCfg *config.BotConfig
for i := range cfg.Bots {
id := cfg.Bots[i].ID
if id == "" {
id = config.GenerateBotID(cfg.Bots[i].Exchange, cfg.Bots[i].Symbol, cfg.Bots[i].GetMarketType())
}
if id == botID {
botCfg = &cfg.Bots[i]
break
}
}
if botCfg == nil {
logger.Warn("BotGroupManager: bot %s not found in config", botID)
continue
}
if err := m.startBotFn(ctx, *botCfg); err != nil {
return err
}
}
// 啟動對沖協調器
coord := strategy.NewHedgeCoordinator(group, m.eventBus)
if err := coord.Start(); err != nil {
logger.Warn("BotGroupManager: hedge coordinator start failed: %v", err)
}
m.coordinators[group.ID] = coord
return nil
}
// StopGroup 停止 Group 內所有 Bot 及對沖協調器
func (m *BotGroupManager) StopGroup(groupID string) error {
m.mu.Lock()
defer m.mu.Unlock()
cfg, err := web.GetLatestConfig()
if err != nil || cfg == nil {
return err
}
var group *config.BotGroup
for i := range cfg.BotGroups {
if cfg.BotGroups[i].ID == groupID {
group = &cfg.BotGroups[i]
break
}
}
if group == nil {
return nil
}
// 停止對沖協調器
if coord, ok := m.coordinators[groupID]; ok {
coord.Stop()
delete(m.coordinators, groupID)
}
// 停止組內每個 Bot
for _, botID := range group.BotIDs {
_ = m.stopBotFn(botID)
}
return nil
}
// GetGroupStatus 聚合 Group 內所有 Bot 的 P&L、風控狀態
func (m *BotGroupManager) GetGroupStatus(groupID string) (map[string]interface{}, bool) {
cfg, err := web.GetLatestConfig()
if err != nil || cfg == nil {
return nil, false
}
for _, g := range cfg.BotGroups {
if g.ID == groupID {
// 簡化:返回組信息,實際 P&L 需從 botManagerProvider 聚合
return map[string]interface{}{
"group_id": g.ID,
"name": g.Name,
"type": g.Type,
"bot_ids": g.BotIDs,
}, true
}
}
return nil, false
}
// OnBotEvent 接收 Bot 事件,判斷是否需要觸發對沖信號
func (m *BotGroupManager) OnBotEvent(evt *event.Event) {
// 由 HedgeCoordinator 通過 Subscribe 訂閱 EventBus 處理
_ = evt
}