Skip to content

Commit a06520f

Browse files
committed
pkg/core: move convert manager to independent file
1 parent 81cceea commit a06520f

File tree

4 files changed

+365
-341
lines changed

4 files changed

+365
-341
lines changed

pkg/core/convert_manager.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package core
2+
3+
import (
4+
"github.com/c9s/bbgo/pkg/types"
5+
"github.com/sirupsen/logrus"
6+
)
7+
8+
type ConverterSetting struct {
9+
SymbolConverter *SymbolConverter `json:"symbolConverter" yaml:"symbolConverter"`
10+
CurrencyConverter *CurrencyConverter `json:"currencyConverter" yaml:"currencyConverter"`
11+
}
12+
13+
func (s *ConverterSetting) getConverter() Converter {
14+
if s.SymbolConverter != nil {
15+
return s.SymbolConverter
16+
}
17+
18+
if s.CurrencyConverter != nil {
19+
return s.CurrencyConverter
20+
}
21+
22+
return nil
23+
}
24+
25+
func (s *ConverterSetting) InitializeConverter() (Converter, error) {
26+
converter := s.getConverter()
27+
if converter == nil {
28+
return nil, nil
29+
}
30+
31+
logrus.Infof("initializing converter %T ...", converter)
32+
err := converter.Initialize()
33+
return converter, err
34+
}
35+
36+
// ConverterManager manages the converters for trade conversion
37+
// It can be used to convert the trade symbol into the target symbol, or convert the price, volume into different units.
38+
type ConverterManager struct {
39+
ConverterSettings []ConverterSetting `json:"converters,omitempty" yaml:"converters,omitempty"`
40+
41+
converters []Converter
42+
}
43+
44+
func (c *ConverterManager) Initialize() error {
45+
for _, setting := range c.ConverterSettings {
46+
converter, err := setting.InitializeConverter()
47+
if err != nil {
48+
return err
49+
}
50+
51+
if converter != nil {
52+
c.AddConverter(converter)
53+
}
54+
}
55+
56+
numConverters := len(c.converters)
57+
logrus.Infof("%d converters loaded", numConverters)
58+
return nil
59+
}
60+
61+
func (c *ConverterManager) AddConverter(converter Converter) {
62+
c.converters = append(c.converters, converter)
63+
}
64+
65+
func (c *ConverterManager) ConvertOrder(order types.Order) types.Order {
66+
if len(c.converters) == 0 {
67+
return order
68+
}
69+
70+
for _, converter := range c.converters {
71+
convOrder, err := converter.ConvertOrder(order)
72+
if err != nil {
73+
logrus.WithError(err).Errorf("converter %+v error, order: %s", converter, order.String())
74+
continue
75+
}
76+
77+
order = convOrder
78+
}
79+
80+
return order
81+
}
82+
83+
func (c *ConverterManager) ConvertTrade(trade types.Trade) types.Trade {
84+
if len(c.converters) == 0 {
85+
return trade
86+
}
87+
88+
for _, converter := range c.converters {
89+
convTrade, err := converter.ConvertTrade(trade)
90+
if err != nil {
91+
logrus.WithError(err).Errorf("converter %+v error, trade: %s", converter, trade.String())
92+
continue
93+
}
94+
95+
trade = convTrade
96+
}
97+
98+
return trade
99+
}
100+
101+
func (c *ConverterManager) ConvertKLine(kline types.KLine) types.KLine {
102+
if len(c.converters) == 0 {
103+
return kline
104+
}
105+
106+
for _, converter := range c.converters {
107+
convKline, err := converter.ConvertKLine(kline)
108+
if err != nil {
109+
logrus.WithError(err).Errorf("converter %+v error, kline: %s", converter, kline.String())
110+
continue
111+
}
112+
113+
kline = convKline
114+
}
115+
116+
return kline
117+
}
118+
119+
func (c *ConverterManager) ConvertMarket(market types.Market) types.Market {
120+
if len(c.converters) == 0 {
121+
return market
122+
}
123+
124+
for _, converter := range c.converters {
125+
convMarket, err := converter.ConvertMarket(market)
126+
if err != nil {
127+
logrus.WithError(err).Errorf("converter %+v error, market: %+v", converter, market)
128+
continue
129+
}
130+
131+
market = convMarket
132+
}
133+
134+
return market
135+
}
136+
137+
func (c *ConverterManager) ConvertBalance(balance types.Balance) types.Balance {
138+
if len(c.converters) == 0 {
139+
return balance
140+
}
141+
142+
for _, converter := range c.converters {
143+
convBal, err := converter.ConvertBalance(balance)
144+
if err != nil {
145+
logrus.WithError(err).Errorf("converter %+v error, balance: %s", converter, balance.String())
146+
continue
147+
}
148+
149+
balance = convBal
150+
}
151+
152+
return balance
153+
}

pkg/core/convert_manager_test.go

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
package core
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/c9s/bbgo/pkg/types"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestInitializeConverter_ValidSymbolConverter(t *testing.T) {
12+
setting := ConverterSetting{
13+
SymbolConverter: &SymbolConverter{
14+
FromSymbol: "MAXEXCHANGEUSDT",
15+
ToSymbol: "MAXUSDT",
16+
},
17+
}
18+
converter, err := setting.InitializeConverter()
19+
assert.NoError(t, err)
20+
assert.NotNil(t, converter)
21+
}
22+
23+
func TestInitializeConverter_ValidCurrencyConverter(t *testing.T) {
24+
setting := ConverterSetting{
25+
CurrencyConverter: &CurrencyConverter{
26+
FromCurrency: "MAXEXCHANGE",
27+
ToCurrency: "MAX",
28+
},
29+
}
30+
converter, err := setting.InitializeConverter()
31+
assert.NoError(t, err)
32+
assert.NotNil(t, converter)
33+
}
34+
35+
func TestInitializeConverter_NoConverter(t *testing.T) {
36+
setting := ConverterSetting{}
37+
converter, err := setting.InitializeConverter()
38+
assert.NoError(t, err)
39+
assert.Nil(t, converter)
40+
}
41+
42+
func TestInitialize_ValidConverters(t *testing.T) {
43+
manager := ConverterManager{
44+
ConverterSettings: []ConverterSetting{
45+
{SymbolConverter: &SymbolConverter{
46+
FromSymbol: "MAXEXCHANGEUSDT",
47+
ToSymbol: "MAXUSDT",
48+
}},
49+
{CurrencyConverter: &CurrencyConverter{
50+
FromCurrency: "MAXEXCHANGE",
51+
ToCurrency: "MAX",
52+
}},
53+
},
54+
}
55+
err := manager.Initialize()
56+
assert.NoError(t, err)
57+
assert.Equal(t, 2, len(manager.converters))
58+
}
59+
60+
func TestInitialize_NoConverters(t *testing.T) {
61+
manager := ConverterManager{}
62+
err := manager.Initialize()
63+
assert.NoError(t, err)
64+
assert.Equal(t, 0, len(manager.converters))
65+
}
66+
67+
func TestConvertOrder_WithConverters(t *testing.T) {
68+
jsonStr := `
69+
{
70+
"converters": [
71+
{
72+
"symbolConverter": {
73+
"from": "MAXEXCHANGEUSDT",
74+
"to": "MAXUSDT"
75+
}
76+
},
77+
{
78+
"currencyConverter": {
79+
"from": "MAXEXCHANGE",
80+
"to": "MAX"
81+
}
82+
}
83+
]
84+
}
85+
`
86+
manager := ConverterManager{}
87+
err := json.Unmarshal([]byte(jsonStr), &manager)
88+
assert.NoError(t, err)
89+
90+
order := types.Order{
91+
SubmitOrder: types.SubmitOrder{
92+
Symbol: "MAXEXCHANGEUSDT",
93+
Market: types.Market{
94+
Symbol: "MAXEXCHANGEUSDT",
95+
QuoteCurrency: "USDT",
96+
BaseCurrency: "MAXEXCHANGE",
97+
},
98+
},
99+
}
100+
err = manager.Initialize()
101+
assert.NoError(t, err)
102+
convertedOrder := manager.ConvertOrder(order)
103+
assert.Equal(t, "MAXUSDT", convertedOrder.Symbol)
104+
assert.Equal(t, "MAX", convertedOrder.Market.BaseCurrency)
105+
assert.Equal(t, "USDT", convertedOrder.Market.QuoteCurrency)
106+
assert.Equal(t, "MAXUSDT", convertedOrder.Market.Symbol)
107+
}
108+
109+
func TestConvertOrder_NoConverters(t *testing.T) {
110+
manager := ConverterManager{}
111+
order := types.Order{}
112+
err := manager.Initialize()
113+
assert.NoError(t, err)
114+
convertedOrder := manager.ConvertOrder(order)
115+
assert.Equal(t, order, convertedOrder)
116+
}
117+
118+
func TestConvertTrade_WithConverters(t *testing.T) {
119+
manager := ConverterManager{}
120+
converter := &CurrencyConverter{
121+
FromCurrency: "MAXEXCHANGE",
122+
ToCurrency: "MAX",
123+
}
124+
err := manager.Initialize()
125+
assert.NoError(t, err)
126+
manager.AddConverter(converter)
127+
128+
trade := types.Trade{}
129+
convertedTrade := manager.ConvertTrade(trade)
130+
assert.Equal(t, trade, convertedTrade)
131+
}
132+
133+
func TestConvertTrade_NoConverters(t *testing.T) {
134+
manager := ConverterManager{}
135+
trade := types.Trade{}
136+
err := manager.Initialize()
137+
assert.NoError(t, err)
138+
convertedTrade := manager.ConvertTrade(trade)
139+
assert.Equal(t, trade, convertedTrade)
140+
}
141+
142+
func TestConvertKLine_WithConverters(t *testing.T) {
143+
manager := ConverterManager{}
144+
converter := &CurrencyConverter{
145+
FromCurrency: "MAXEXCHANGE",
146+
ToCurrency: "MAX",
147+
}
148+
err := manager.Initialize()
149+
assert.NoError(t, err)
150+
manager.AddConverter(converter)
151+
152+
kline := types.KLine{}
153+
convertedKline := manager.ConvertKLine(kline)
154+
assert.Equal(t, kline, convertedKline)
155+
}
156+
157+
func TestConvertKLine_NoConverters(t *testing.T) {
158+
manager := ConverterManager{}
159+
kline := types.KLine{}
160+
err := manager.Initialize()
161+
assert.NoError(t, err)
162+
convertedKline := manager.ConvertKLine(kline)
163+
assert.Equal(t, kline, convertedKline)
164+
}
165+
166+
func TestConvertMarket_WithConverters(t *testing.T) {
167+
manager := ConverterManager{}
168+
converter := &CurrencyConverter{
169+
FromCurrency: "MAXEXCHANGE",
170+
ToCurrency: "MAX",
171+
}
172+
err := manager.Initialize()
173+
assert.NoError(t, err)
174+
manager.AddConverter(converter)
175+
176+
market := types.Market{}
177+
convertedMarket := manager.ConvertMarket(market)
178+
assert.Equal(t, market, convertedMarket)
179+
}
180+
181+
func TestConvertMarket_NoConverters(t *testing.T) {
182+
manager := ConverterManager{}
183+
market := types.Market{}
184+
err := manager.Initialize()
185+
assert.NoError(t, err)
186+
convertedMarket := manager.ConvertMarket(market)
187+
assert.Equal(t, market, convertedMarket)
188+
}
189+
190+
func TestConvertBalance_WithConverters(t *testing.T) {
191+
manager := ConverterManager{}
192+
converter := &CurrencyConverter{
193+
FromCurrency: "MAXEXCHANGE",
194+
ToCurrency: "MAX",
195+
}
196+
err := manager.Initialize()
197+
assert.NoError(t, err)
198+
manager.AddConverter(converter)
199+
200+
balance := types.Balance{}
201+
convertedBalance := manager.ConvertBalance(balance)
202+
assert.Equal(t, balance, convertedBalance)
203+
}
204+
205+
func TestConvertBalance_NoConverters(t *testing.T) {
206+
manager := ConverterManager{}
207+
balance := types.Balance{}
208+
err := manager.Initialize()
209+
assert.NoError(t, err)
210+
convertedBalance := manager.ConvertBalance(balance)
211+
assert.Equal(t, balance, convertedBalance)
212+
}

0 commit comments

Comments
 (0)