engine/exchanges: Add GetCurrencyTradeURL wrapper func/gRPC endpoint (#1521)

* beginning the concept

* expands testing and implementations

* test standardisation, expansion

* more

* finish remainder, add rpc func

* lint

* grammar? I barely know her!

* wow i forgot something wow wow wow wow

* rm SendPayload

* enFixio!

* improve binance long-dated support

* update test design, update wrapper funcs

* adds kraken futures, adds bybit support

* fixes SIMPLE bugs

* s is for sucks

* fixed option url x2

* fixed silly test
This commit is contained in:
Scott
2024-05-03 17:01:17 +10:00
committed by GitHub
parent 0676c78bec
commit f1ff951199
83 changed files with 3922 additions and 2265 deletions

View File

@@ -16,6 +16,7 @@ const (
// Bitflyer chain analysis endpoints
// APIURL
chainAnalysis = "https://chainflyer.bitflyer.jp/v1/"
tradeBaseURL = "https://lightning.bitflyer.com/trade/"
// Public endpoints for chain analysis
latestBlock = "block/latest"

View File

@@ -7,6 +7,8 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/core"
@@ -15,6 +17,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
testexch "github.com/thrasher-corp/gocryptotrader/internal/testing/exchange"
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
)
@@ -155,24 +158,14 @@ func TestCheckFXString(t *testing.T) {
func TestFetchTicker(t *testing.T) {
t.Parallel()
var p currency.Pair
testexch.UpdatePairsOnce(t, b)
currencies, err := b.GetAvailablePairs(asset.Spot)
if err != nil {
t.Fatal(err)
}
for i := range currencies {
if currencies[i].String() == "FXBTC_JPY" {
p = currencies[i]
break
}
}
_, err = b.FetchTicker(context.Background(), p, asset.Spot)
if err != nil {
t.Error("Bitflyer - FetchTicker() error", err)
}
require.GreaterOrEqual(t, len(currencies), 1)
_, err = b.FetchTicker(context.Background(), currencies[0], asset.Spot)
assert.NoError(t, err)
}
func setFeeBuilder() *exchange.FeeBuilder {
@@ -453,3 +446,23 @@ func TestGetHistoricTrades(t *testing.T) {
t.Fatal(err)
}
}
func TestUpdateTradablePairs(t *testing.T) {
t.Parallel()
testexch.UpdatePairsOnce(t, b)
}
func TestGetCurrencyTradeURL(t *testing.T) {
t.Parallel()
testexch.UpdatePairsOnce(t, b)
err := b.CurrencyPairs.SetAssetEnabled(asset.Futures, true)
require.NoError(t, err)
for _, a := range b.GetAssetTypes(false) {
pairs, err := b.CurrencyPairs.GetPairs(a, false)
require.NoError(t, err, "cannot get pairs for %s", a)
require.NotEmpty(t, pairs, "no pairs for %s", a)
resp, err := b.GetCurrencyTradeURL(context.Background(), a, pairs[0])
require.NoError(t, err)
assert.NotEmpty(t, resp)
}
}

View File

@@ -1,5 +1,9 @@
package bitflyer
import "errors"
var errUnhandledCurrency = errors.New("unhandled currency")
// ChainAnalysisBlock holds block information from the bitcoin network
type ChainAnalysisBlock struct {
BlockHash string `json:"block_hash"`

View File

@@ -106,27 +106,23 @@ func (b *Bitflyer) FetchTradablePairs(ctx context.Context, a asset.Item) (curren
if err != nil {
return nil, err
}
format, err := b.GetPairFormat(a, false)
if err != nil {
return nil, err
}
pairs := make([]currency.Pair, 0, len(symbols))
for i := range symbols {
var pair currency.Pair
if symbols[i].Alias != "" && a == asset.Futures {
pair, err = currency.NewPairFromString(symbols[i].Alias)
if err != nil {
return nil, err
}
pairs = append(pairs, pair)
} else if symbols[i].Alias == "" &&
a == asset.Spot &&
strings.Contains(symbols[i].ProductCode, format.Delimiter) {
if a == asset.Spot && symbols[i].MarketType == "Spot" {
pair, err = currency.NewPairFromString(symbols[i].ProductCode)
if err != nil {
return nil, err
}
pairs = append(pairs, pair)
} else if a == asset.Futures && symbols[i].MarketType == "FX" {
splitter := strings.Split(symbols[i].ProductCode, currency.UnderscoreDelimiter)
if len(splitter) != 3 {
return nil, fmt.Errorf("%w %s", errUnhandledCurrency, symbols[i].ProductCode)
}
pair = currency.NewPair(currency.NewCode(splitter[0]+splitter[1]), currency.NewCode(splitter[2]))
pair.Delimiter = currency.UnderscoreDelimiter
pairs = append(pairs, pair)
}
}
return pairs, nil
@@ -136,13 +132,12 @@ func (b *Bitflyer) FetchTradablePairs(ctx context.Context, a asset.Item) (curren
// them in the exchanges config
func (b *Bitflyer) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error {
assets := b.CurrencyPairs.GetAssetTypes(false)
for x := range assets {
pairs, err := b.FetchTradablePairs(ctx, assets[x])
for _, a := range assets {
pairs, err := b.FetchTradablePairs(ctx, a)
if err != nil {
return err
}
err = b.UpdatePairs(pairs, assets[x], false, forceUpdate)
err = b.UpdatePairs(pairs, a, false, forceUpdate)
if err != nil {
return err
}
@@ -462,3 +457,13 @@ func (b *Bitflyer) GetLatestFundingRates(context.Context, *fundingrate.LatestRat
func (b *Bitflyer) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error {
return common.ErrNotYetImplemented
}
// GetCurrencyTradeURL returns the URL to the exchange's trade page for the given asset and currency pair
func (b *Bitflyer) GetCurrencyTradeURL(_ context.Context, a asset.Item, cp currency.Pair) (string, error) {
_, err := b.CurrencyPairs.IsPairEnabled(cp, a)
if err != nil {
return "", err
}
cp.Delimiter = ""
return tradeBaseURL + cp.Lower().String(), nil
}