mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-23 23:35:14 +00:00
pkg/core: add currency converter
This commit is contained in:
parent
b683550f44
commit
4fefbaf0e7
68
pkg/core/currency_converter.go
Normal file
68
pkg/core/currency_converter.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CurrencyConverter struct {
|
||||||
|
FromCurrency string `json:"from"`
|
||||||
|
ToCurrency string `json:"to"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCurrencyConverter(fromSymbol, toSymbol string) *CurrencyConverter {
|
||||||
|
return &CurrencyConverter{FromCurrency: fromSymbol, ToCurrency: toSymbol}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) Initialize() error {
|
||||||
|
if c.FromCurrency == "" {
|
||||||
|
return errors.New("FromCurrency can not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.ToCurrency == "" {
|
||||||
|
return errors.New("ToCurrency can not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) ConvertOrder(order types.Order) (types.Order, error) {
|
||||||
|
if order.SubmitOrder.Market.QuoteCurrency == c.FromCurrency {
|
||||||
|
order.SubmitOrder.Market.QuoteCurrency = c.ToCurrency
|
||||||
|
}
|
||||||
|
if order.SubmitOrder.Market.BaseCurrency == c.FromCurrency {
|
||||||
|
order.SubmitOrder.Market.BaseCurrency = c.ToCurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
return order, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) ConvertTrade(trade types.Trade) (types.Trade, error) {
|
||||||
|
if trade.FeeCurrency == c.FromCurrency {
|
||||||
|
trade.FeeCurrency = c.ToCurrency
|
||||||
|
}
|
||||||
|
return trade, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) ConvertKLine(kline types.KLine) (types.KLine, error) {
|
||||||
|
return kline, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) ConvertMarket(mkt types.Market) (types.Market, error) {
|
||||||
|
if mkt.QuoteCurrency == c.FromCurrency {
|
||||||
|
mkt.QuoteCurrency = c.ToCurrency
|
||||||
|
}
|
||||||
|
if mkt.BaseCurrency == c.FromCurrency {
|
||||||
|
mkt.BaseCurrency = c.ToCurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
return mkt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CurrencyConverter) ConvertBalance(balance types.Balance) (types.Balance, error) {
|
||||||
|
if balance.Currency == c.FromCurrency {
|
||||||
|
balance.Currency = c.ToCurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
return balance, nil
|
||||||
|
}
|
124
pkg/core/currency_converter_test.go
Normal file
124
pkg/core/currency_converter_test.go
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// pkg/core/tradecollector_test.go
|
||||||
|
func TestInitialize_ValidCurrencies(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
err := converter.Initialize()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitialize_EmptyFromCurrency(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("", "MAX")
|
||||||
|
err := converter.Initialize()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "FromCurrency can not be empty", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitialize_EmptyToCurrency(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "")
|
||||||
|
err := converter.Initialize()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, "ToCurrency can not be empty", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertOrder_ValidConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
order := types.Order{
|
||||||
|
SubmitOrder: types.SubmitOrder{
|
||||||
|
Market: types.Market{
|
||||||
|
QuoteCurrency: "MAXEXCHANGE",
|
||||||
|
BaseCurrency: "MAXEXCHANGE",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
convertedOrder, err := converter.ConvertOrder(order)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "MAX", convertedOrder.SubmitOrder.Market.QuoteCurrency)
|
||||||
|
assert.Equal(t, "MAX", convertedOrder.SubmitOrder.Market.BaseCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertOrder_NoConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
order := types.Order{
|
||||||
|
SubmitOrder: types.SubmitOrder{
|
||||||
|
Market: types.Market{
|
||||||
|
QuoteCurrency: "JPY",
|
||||||
|
BaseCurrency: "JPY",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
convertedOrder, err := converter.ConvertOrder(order)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "JPY", convertedOrder.SubmitOrder.Market.QuoteCurrency)
|
||||||
|
assert.Equal(t, "JPY", convertedOrder.SubmitOrder.Market.BaseCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertTrade_ValidConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
trade := types.Trade{
|
||||||
|
FeeCurrency: "MAXEXCHANGE",
|
||||||
|
}
|
||||||
|
convertedTrade, err := converter.ConvertTrade(trade)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "MAX", convertedTrade.FeeCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertTrade_NoConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
trade := types.Trade{
|
||||||
|
FeeCurrency: "JPY",
|
||||||
|
}
|
||||||
|
convertedTrade, err := converter.ConvertTrade(trade)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "JPY", convertedTrade.FeeCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertMarket_ValidConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
market := types.Market{
|
||||||
|
QuoteCurrency: "MAXEXCHANGE",
|
||||||
|
BaseCurrency: "MAXEXCHANGE",
|
||||||
|
}
|
||||||
|
convertedMarket, err := converter.ConvertMarket(market)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "MAX", convertedMarket.QuoteCurrency)
|
||||||
|
assert.Equal(t, "MAX", convertedMarket.BaseCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertMarket_NoConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
market := types.Market{
|
||||||
|
QuoteCurrency: "JPY",
|
||||||
|
BaseCurrency: "JPY",
|
||||||
|
}
|
||||||
|
convertedMarket, err := converter.ConvertMarket(market)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "JPY", convertedMarket.QuoteCurrency)
|
||||||
|
assert.Equal(t, "JPY", convertedMarket.BaseCurrency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertBalance_ValidConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
balance := types.Balance{
|
||||||
|
Currency: "MAXEXCHANGE",
|
||||||
|
}
|
||||||
|
convertedBalance, err := converter.ConvertBalance(balance)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "MAX", convertedBalance.Currency)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertBalance_NoConversion(t *testing.T) {
|
||||||
|
converter := NewCurrencyConverter("MAXEXCHANGE", "MAX")
|
||||||
|
balance := types.Balance{
|
||||||
|
Currency: "JPY",
|
||||||
|
}
|
||||||
|
convertedBalance, err := converter.ConvertBalance(balance)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "JPY", convertedBalance.Currency)
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import (
|
||||||
|
|
||||||
type ConverterSetting struct {
|
type ConverterSetting struct {
|
||||||
SymbolConverter *SymbolConverter `json:"symbolConverter" yaml:"symbolConverter"`
|
SymbolConverter *SymbolConverter `json:"symbolConverter" yaml:"symbolConverter"`
|
||||||
|
CurrencyConverter *CurrencyConverter `json:"currencyConverter" yaml:"currencyConverter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ConverterSetting) getConverter() Converter {
|
func (s *ConverterSetting) getConverter() Converter {
|
||||||
|
@ -21,6 +22,10 @@ func (s *ConverterSetting) getConverter() Converter {
|
||||||
return s.SymbolConverter
|
return s.SymbolConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.CurrencyConverter != nil {
|
||||||
|
return s.CurrencyConverter
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user