mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
currency: Add OrderParameters helpers for currency pair (#1217)
* currency: Add order aspect from pair helper method. * Update currency/pair_methods.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update currency/pair_types.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * glorious: nit cont. rm pair field and used IsPopulated method instead of IsEmpty * thrasher: nits * ch test name * glorious: nits --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com>
This commit is contained in:
@@ -2,11 +2,15 @@ package currency
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// EMPTYFORMAT defines an empty pair format
|
||||
var EMPTYFORMAT = PairFormat{}
|
||||
|
||||
var errCurrencyNotAssociatedWithPair = errors.New("currency not associated with pair")
|
||||
|
||||
// String returns a currency pair string
|
||||
func (p Pair) String() string {
|
||||
return p.Base.String() + p.Delimiter + p.Quote.String()
|
||||
@@ -140,7 +144,82 @@ func (p Pair) Other(c Code) (Code, error) {
|
||||
return EMPTYCODE, ErrCurrencyCodeEmpty
|
||||
}
|
||||
|
||||
// IsPopulated returns true if the currency pair have both non-empty values for base and quote.
|
||||
// IsPopulated returns true if the currency pair have both non-empty values for
|
||||
// base and quote.
|
||||
func (p Pair) IsPopulated() bool {
|
||||
return !p.Base.IsEmpty() && !p.Quote.IsEmpty()
|
||||
}
|
||||
|
||||
// MarketSellOrderParameters returns order parameters for when you want to sell
|
||||
// a currency which purchases another currency. This specifically returns what
|
||||
// liquidity side you will be affecting, what order side you will be placing and
|
||||
// what currency you will be purchasing.
|
||||
func (p Pair) MarketSellOrderParameters(wantingToSell Code) (*OrderParameters, error) {
|
||||
return p.getOrderParameters(wantingToSell, true, true)
|
||||
}
|
||||
|
||||
// MarketBuyOrderParameters returns order parameters for when you want to sell a
|
||||
// currency which purchases another currency. This specifically returns what
|
||||
// liquidity side you will be affecting, what order side you will be placing and
|
||||
// what currency you will be purchasing.
|
||||
func (p Pair) MarketBuyOrderParameters(wantingToBuy Code) (*OrderParameters, error) {
|
||||
return p.getOrderParameters(wantingToBuy, false, true)
|
||||
}
|
||||
|
||||
// LimitSellOrderParameters returns order parameters for when you want to sell a
|
||||
// currency which purchases another currency. This specifically returns what
|
||||
// liquidity side you will be affecting, what order side you will be placing and
|
||||
// what currency you will be purchasing.
|
||||
func (p Pair) LimitSellOrderParameters(wantingToSell Code) (*OrderParameters, error) {
|
||||
return p.getOrderParameters(wantingToSell, true, false)
|
||||
}
|
||||
|
||||
// LimitBuyOrderParameters returns order parameters for when you want to
|
||||
// sell a currency which purchases another currency. This specifically returns
|
||||
// what liquidity side you will be affecting, what order side you will be
|
||||
// placing and what currency you will be purchasing.
|
||||
func (p Pair) LimitBuyOrderParameters(wantingToBuy Code) (*OrderParameters, error) {
|
||||
return p.getOrderParameters(wantingToBuy, false, false)
|
||||
}
|
||||
|
||||
// getOrderDecisionDetails returns order parameters for the currency pair using
|
||||
// the provided currency code, whether or not you are selling and whether or not
|
||||
// you are placing a market order.
|
||||
func (p Pair) getOrderParameters(c Code, selling, market bool) (*OrderParameters, error) {
|
||||
if !p.IsPopulated() {
|
||||
return nil, ErrCurrencyPairEmpty
|
||||
}
|
||||
if c.IsEmpty() {
|
||||
return nil, ErrCurrencyCodeEmpty
|
||||
}
|
||||
params := OrderParameters{}
|
||||
switch {
|
||||
case p.Base.Equal(c):
|
||||
if selling {
|
||||
params.SellingCurrency = p.Base
|
||||
params.PurchasingCurrency = p.Quote
|
||||
params.IsBuySide = false
|
||||
params.IsAskLiquidity = !market
|
||||
} else {
|
||||
params.SellingCurrency = p.Quote
|
||||
params.PurchasingCurrency = p.Base
|
||||
params.IsBuySide = true
|
||||
params.IsAskLiquidity = market
|
||||
}
|
||||
case p.Quote.Equal(c):
|
||||
if selling {
|
||||
params.SellingCurrency = p.Quote
|
||||
params.PurchasingCurrency = p.Base
|
||||
params.IsBuySide = true
|
||||
params.IsAskLiquidity = market
|
||||
} else {
|
||||
params.SellingCurrency = p.Base
|
||||
params.PurchasingCurrency = p.Quote
|
||||
params.IsBuySide = false
|
||||
params.IsAskLiquidity = !market
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("%w %v: %v", errCurrencyNotAssociatedWithPair, c, p)
|
||||
}
|
||||
return ¶ms, nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package currency
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -961,3 +962,77 @@ func TestIsPopulated(t *testing.T) {
|
||||
t.Fatal("unexpected value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := NewPair(BTC, USDT)
|
||||
testCases := []struct {
|
||||
Pair Pair
|
||||
currency Code
|
||||
market bool
|
||||
selling bool
|
||||
expectedParams *OrderParameters
|
||||
expectedError error
|
||||
}{
|
||||
{expectedError: ErrCurrencyPairEmpty},
|
||||
{Pair: p, expectedError: ErrCurrencyCodeEmpty},
|
||||
{Pair: p, currency: XRP, selling: true, market: true, expectedError: errCurrencyNotAssociatedWithPair},
|
||||
|
||||
{Pair: p, currency: BTC, selling: true, market: true, expectedParams: &OrderParameters{SellingCurrency: BTC, PurchasingCurrency: USDT, IsBuySide: false, IsAskLiquidity: false}},
|
||||
{Pair: p, currency: BTC, selling: false, market: true, expectedParams: &OrderParameters{SellingCurrency: USDT, PurchasingCurrency: BTC, IsBuySide: true, IsAskLiquidity: true}},
|
||||
{Pair: p, currency: BTC, selling: true, market: false, expectedParams: &OrderParameters{SellingCurrency: BTC, PurchasingCurrency: USDT, IsBuySide: false, IsAskLiquidity: true}},
|
||||
{Pair: p, currency: BTC, selling: false, market: false, expectedParams: &OrderParameters{SellingCurrency: USDT, PurchasingCurrency: BTC, IsBuySide: true, IsAskLiquidity: false}},
|
||||
|
||||
{Pair: p, currency: USDT, selling: true, market: true, expectedParams: &OrderParameters{SellingCurrency: USDT, PurchasingCurrency: BTC, IsBuySide: true, IsAskLiquidity: true}},
|
||||
{Pair: p, currency: USDT, selling: false, market: true, expectedParams: &OrderParameters{SellingCurrency: BTC, PurchasingCurrency: USDT, IsBuySide: false, IsAskLiquidity: false}},
|
||||
{Pair: p, currency: USDT, selling: true, market: false, expectedParams: &OrderParameters{SellingCurrency: USDT, PurchasingCurrency: BTC, IsBuySide: true, IsAskLiquidity: false}},
|
||||
{Pair: p, currency: USDT, selling: false, market: false, expectedParams: &OrderParameters{SellingCurrency: BTC, PurchasingCurrency: USDT, IsBuySide: false, IsAskLiquidity: true}},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var resp *OrderParameters
|
||||
var err error
|
||||
switch {
|
||||
case tc.market && tc.selling:
|
||||
resp, err = tc.Pair.MarketSellOrderParameters(tc.currency)
|
||||
case tc.market && !tc.selling:
|
||||
resp, err = tc.Pair.MarketBuyOrderParameters(tc.currency)
|
||||
case !tc.market && tc.selling:
|
||||
resp, err = tc.Pair.LimitSellOrderParameters(tc.currency)
|
||||
case !tc.market && !tc.selling:
|
||||
resp, err = tc.Pair.LimitBuyOrderParameters(tc.currency)
|
||||
}
|
||||
|
||||
if !errors.Is(err, tc.expectedError) {
|
||||
t.Fatalf("received %v, expected %v", err, tc.expectedError)
|
||||
}
|
||||
|
||||
if tc.expectedParams == nil {
|
||||
if resp != nil {
|
||||
t.Fatalf("received %v, expected nil", resp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if resp.SellingCurrency != tc.expectedParams.SellingCurrency {
|
||||
t.Fatalf("SellingCurrency received %v, expected %v", resp.SellingCurrency, tc.expectedParams.SellingCurrency)
|
||||
}
|
||||
|
||||
if resp.PurchasingCurrency != tc.expectedParams.PurchasingCurrency {
|
||||
t.Fatalf("PurchasingCurrency received %v, expected %v", resp.PurchasingCurrency, tc.expectedParams.PurchasingCurrency)
|
||||
}
|
||||
|
||||
if resp.IsBuySide != tc.expectedParams.IsBuySide {
|
||||
t.Fatalf("BuySide received %v, expected %v", resp.IsBuySide, tc.expectedParams.IsBuySide)
|
||||
}
|
||||
|
||||
if resp.IsAskLiquidity != tc.expectedParams.IsAskLiquidity {
|
||||
t.Fatalf("AskLiquidity received %v, expected %v", resp.IsAskLiquidity, tc.expectedParams.IsAskLiquidity)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,3 +17,18 @@ type PairDifference struct {
|
||||
Remove Pairs
|
||||
FormatDifference bool
|
||||
}
|
||||
|
||||
// OrderParameters is used to determine the order side, liquidity side and the
|
||||
// selling & purchasing currency derived from the currency pair.
|
||||
type OrderParameters struct {
|
||||
// SellingCurrency is the currency that will be sold first
|
||||
SellingCurrency Code
|
||||
// Purchasing is the currency that will be purchased last
|
||||
PurchasingCurrency Code
|
||||
// IsBuySide is the side of the order that will be placed true for buy/long,
|
||||
// false for sell/short.
|
||||
IsBuySide bool
|
||||
// IsAskLiquidity is the side of the orderbook that will be used, false for
|
||||
// bid liquidity.
|
||||
IsAskLiquidity bool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user