diff --git a/config/marketcap.yaml b/config/marketcap.yaml index 47bc14796..c3e7b7285 100644 --- a/config/marketcap.yaml +++ b/config/marketcap.yaml @@ -13,6 +13,11 @@ exchangeStrategies: targetCurrencies: - BTC - ETH + # - BNB + # - ADA + # - SOL + # - DOT + # - DOGE - MATIC threshold: 2% # max amount to buy or sell per order diff --git a/pkg/datasource/coinmarketcap/datasource.go b/pkg/datasource/coinmarketcap/datasource.go index 9ea5b8282..50e5b4238 100644 --- a/pkg/datasource/coinmarketcap/datasource.go +++ b/pkg/datasource/coinmarketcap/datasource.go @@ -1,6 +1,10 @@ package coinmarketcap -import v1 "github.com/c9s/bbgo/pkg/datasource/coinmarketcap/v1" +import ( + "context" + + v1 "github.com/c9s/bbgo/pkg/datasource/coinmarketcap/v1" +) type DataSource struct { client *v1.RestClient @@ -11,3 +15,22 @@ func New(apiKey string) *DataSource { client.Auth(apiKey) return &DataSource{client: client} } + +func (d *DataSource) QueryMarketCapInUSD(ctx context.Context, limit int) (map[string]float64, error) { + req := v1.ListingsLatestRequest{ + Client: d.client, + Limit: &limit, + } + + resp, err := req.Do(ctx) + if err != nil { + return nil, err + } + + marketcaps := make(map[string]float64) + for _, data := range resp { + marketcaps[data.Symbol] = data.Quote["USD"].MarketCap + } + + return marketcaps, nil +} diff --git a/pkg/strategy/marketcap/strategy.go b/pkg/strategy/marketcap/strategy.go index 36e5c9a74..b0cba5e3f 100644 --- a/pkg/strategy/marketcap/strategy.go +++ b/pkg/strategy/marketcap/strategy.go @@ -8,7 +8,7 @@ import ( "github.com/sirupsen/logrus" "github.com/c9s/bbgo/pkg/bbgo" - "github.com/c9s/bbgo/pkg/datasource/glassnode" + "github.com/c9s/bbgo/pkg/datasource/coinmarketcap" "github.com/c9s/bbgo/pkg/datatype/floats" "github.com/c9s/bbgo/pkg/fixedpoint" "github.com/c9s/bbgo/pkg/types" @@ -23,15 +23,13 @@ func init() { } type Strategy struct { - Notifiability *bbgo.Notifiability - glassnode *glassnode.DataSource + datasource *coinmarketcap.DataSource Interval types.Interval `json:"interval"` BaseCurrency string `json:"baseCurrency"` BaseWeight fixedpoint.Value `json:"baseWeight"` TargetCurrencies []string `json:"targetCurrencies"` Threshold fixedpoint.Value `json:"threshold"` - Verbose bool `json:"verbose"` DryRun bool `json:"dryRun"` // max amount to buy or sell per order MaxAmount fixedpoint.Value `json:"maxAmount"` @@ -40,8 +38,8 @@ type Strategy struct { } func (s *Strategy) Initialize() error { - apiKey := os.Getenv("GLASSNODE_API_KEY") - s.glassnode = glassnode.New(apiKey) + apiKey := os.Getenv("COINMARKETCAP_API_KEY") + s.datasource = coinmarketcap.New(apiKey) return nil } @@ -177,14 +175,15 @@ func (s *Strategy) generateSubmitOrders(ctx context.Context, session *bbgo.Excha func (s *Strategy) getTargetWeights(ctx context.Context) types.ValueMap { m := floats.Map{} - // get market cap values + // get marketcap from coinmarketcap + // set higher query limit to avoid target currency not in the list + marketcaps, err := s.datasource.QueryMarketCapInUSD(ctx, 100) + if err != nil { + log.WithError(err).Error("failed to query market cap") + } + for _, currency := range s.TargetCurrencies { - marketCap, err := s.glassnode.QueryMarketCapInUSD(ctx, currency) - if err != nil { - log.WithError(err).Error("failed to query market cap") - return nil - } - m[currency] = marketCap + m[currency] = marketcaps[currency] } // normalize