mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-14 15:09:51 +00:00
* depth: methods to derive liquidity impact details * depth: fix comments on link list methods * depth: fix whoopsie * Update exchanges/orderbook/linked_list_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * orderbook: standardise methods to GCT math package * averagePrice: implementation (WIP) * ll: hmmmmmm * continued * orderbook: reworked functions * WIP * orderbook: add tests link up with RPC * orderbook: refined calculations, add tests (WIP) * orderbook: add tests finalise/verify remove state until next PR if needed * rpcserver/orderbook: remove redundant type and change wording * linter: fix * Update exchanges/orderbook/linked_list.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * gctcli: noobed it up * orderbook: work work work (yesterday) * depth: WIP and testing * orderbook: improve calculations for bids traversal * orderbook: adjust tests * orderbook: linters/nits * orderbook: fix error returns and add asset to whalebomb * orderbook: drop error when full book is potentially consumed * Update cmd/gctcli/orderbook.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * orderbook: Add tests and nits * glorious: nits * backtester: handle new errors * grpc: linter * orderbook: remove pesky t.Log()s * glorious: nits (yesterday) * depth/gctcli: Add in purchase requirements into orderbook movement, will also standardize in next commit after tests are fixed. * orderbook: standardize and overhaul * orderbook: update comments, update tests * rpcserver: add average ordercost and amounts * depth: add spread and imbalance methods * linter: fix * glorious: nits * orderbook: don't purge price, rn test. * glorious: codes nits * linter: fix * Update exchanges/orderbook/linked_list.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/orderbook/linked_list.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/orderbook/linked_list.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/orderbook/linked_list.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/orderbook/linked_list.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher: nits Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
2124 lines
63 KiB
Go
2124 lines
63 KiB
Go
package orderbook
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
)
|
|
|
|
var id = uuid.Must(uuid.NewV4())
|
|
|
|
func TestGetLength(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
err := d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
_, err = d.GetAskLength()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.LoadSnapshot([]Item{{Price: 1337}}, nil, 0, time.Time{}, true)
|
|
|
|
askLen, err := d.GetAskLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if askLen != 0 {
|
|
t.Errorf("expected len %v, but received %v", 0, askLen)
|
|
}
|
|
|
|
d.asks.load([]Item{{Price: 1337}}, d.stack)
|
|
|
|
askLen, err = d.GetAskLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if askLen != 1 {
|
|
t.Errorf("expected len %v, but received %v", 1, askLen)
|
|
}
|
|
|
|
d = NewDepth(id)
|
|
err = d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
_, err = d.GetBidLength()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.LoadSnapshot(nil, []Item{{Price: 1337}}, 0, time.Time{}, true)
|
|
|
|
bidLen, err := d.GetBidLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if bidLen != 0 {
|
|
t.Errorf("expected len %v, but received %v", 0, bidLen)
|
|
}
|
|
|
|
d.bids.load([]Item{{Price: 1337}}, d.stack)
|
|
|
|
bidLen, err = d.GetBidLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if bidLen != 1 {
|
|
t.Errorf("expected len %v, but received %v", 1, bidLen)
|
|
}
|
|
}
|
|
|
|
func TestRetrieve(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.asks.load([]Item{{Price: 1337}}, d.stack)
|
|
d.bids.load([]Item{{Price: 1337}}, d.stack)
|
|
d.options = options{
|
|
exchange: "THE BIG ONE!!!!!!",
|
|
pair: currency.NewPair(currency.THETA, currency.USD),
|
|
asset: asset.DownsideProfitContract,
|
|
lastUpdated: time.Now(),
|
|
lastUpdateID: 1337,
|
|
priceDuplication: true,
|
|
isFundingRate: true,
|
|
VerifyOrderbook: true,
|
|
restSnapshot: true,
|
|
idAligned: true,
|
|
}
|
|
|
|
// If we add anymore options to the options struct later this will complain
|
|
// generally want to return a full carbon copy
|
|
mirrored := reflect.Indirect(reflect.ValueOf(d.options))
|
|
for n := 0; n < mirrored.NumField(); n++ {
|
|
structVal := mirrored.Field(n)
|
|
if structVal.IsZero() {
|
|
t.Fatalf("struct value options not set for field %v",
|
|
mirrored.Type().Field(n).Name)
|
|
}
|
|
}
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if len(ob.Asks) != 1 {
|
|
t.Errorf("expected len %v, but received %v", 1, len(ob.Bids))
|
|
}
|
|
|
|
if len(ob.Bids) != 1 {
|
|
t.Errorf("expected len %v, but received %v", 1, len(ob.Bids))
|
|
}
|
|
}
|
|
|
|
func TestTotalAmounts(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
|
|
err := d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
_, _, err = d.TotalBidAmounts()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.validationError = nil
|
|
liquidity, value, err := d.TotalBidAmounts()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if liquidity != 0 || value != 0 {
|
|
t.Fatalf("liquidity expected %f received %f value expected %f received %f",
|
|
0.,
|
|
liquidity,
|
|
0.,
|
|
value)
|
|
}
|
|
|
|
err = d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
_, _, err = d.TotalAskAmounts()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.validationError = nil
|
|
|
|
liquidity, value, err = d.TotalAskAmounts()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if liquidity != 0 || value != 0 {
|
|
t.Fatalf("liquidity expected %f received %f value expected %f received %f",
|
|
0.,
|
|
liquidity,
|
|
0.,
|
|
value)
|
|
}
|
|
|
|
d.asks.load([]Item{{Price: 1337, Amount: 1}}, d.stack)
|
|
d.bids.load([]Item{{Price: 1337, Amount: 10}}, d.stack)
|
|
|
|
liquidity, value, err = d.TotalBidAmounts()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if liquidity != 10 || value != 13370 {
|
|
t.Fatalf("liquidity expected %f received %f value expected %f received %f",
|
|
10.,
|
|
liquidity,
|
|
13370.,
|
|
value)
|
|
}
|
|
|
|
liquidity, value, err = d.TotalAskAmounts()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if liquidity != 1 || value != 1337 {
|
|
t.Fatalf("liquidity expected %f received %f value expected %f received %f",
|
|
1.,
|
|
liquidity,
|
|
1337.,
|
|
value)
|
|
}
|
|
}
|
|
|
|
func TestLoadSnapshot(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1}}, Items{{Price: 1337, Amount: 10}}, 0, time.Time{}, false)
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if ob.Asks[0].Price != 1337 || ob.Bids[0].Price != 1337 {
|
|
t.Fatalf("not set")
|
|
}
|
|
}
|
|
|
|
func TestInvalidate(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.exchange = "testexchange"
|
|
d.pair = currency.NewPair(currency.BTC, currency.WABI)
|
|
d.asset = asset.Spot
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1}}, Items{{Price: 1337, Amount: 10}}, 0, time.Time{}, false)
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if ob == nil {
|
|
t.Fatalf("unexpected value")
|
|
}
|
|
|
|
err = d.Invalidate(errors.New("random reason"))
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
_, err = d.Retrieve()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
if err.Error() != "testexchange BTCWABI spot orderbook data integrity compromised Reason: [random reason]" {
|
|
t.Fatal("unexpected string return")
|
|
}
|
|
|
|
d.validationError = nil
|
|
|
|
ob, err = d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if len(ob.Asks) != 0 || len(ob.Bids) != 0 {
|
|
t.Fatalf("not flushed")
|
|
}
|
|
}
|
|
|
|
func TestUpdateBidAskByPrice(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
// empty
|
|
d.UpdateBidAskByPrice(&Update{})
|
|
|
|
updates := &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 1}},
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 2}},
|
|
UpdateID: 1,
|
|
}
|
|
d.UpdateBidAskByPrice(updates)
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if ob.Asks[0].Amount != 2 || ob.Bids[0].Amount != 2 {
|
|
t.Fatalf("orderbook amounts not updated correctly")
|
|
}
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1337, Amount: 0, ID: 1}},
|
|
Asks: Items{{Price: 1337, Amount: 0, ID: 2}},
|
|
UpdateID: 2,
|
|
}
|
|
d.UpdateBidAskByPrice(updates)
|
|
|
|
askLen, err := d.GetAskLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
bidLen, err := d.GetBidLength()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if askLen != 0 || bidLen != 0 {
|
|
t.Fatalf("orderbook amounts not updated correctly")
|
|
}
|
|
}
|
|
|
|
func TestDeleteBidAskByID(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates := &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 1}},
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 2}},
|
|
}
|
|
err := d.DeleteBidAskByID(updates, false)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if len(ob.Asks) != 0 || len(ob.Bids) != 0 {
|
|
t.Fatalf("items not deleted")
|
|
}
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 1}},
|
|
}
|
|
err = d.DeleteBidAskByID(updates, false)
|
|
if !strings.Contains(err.Error(), errIDCannotBeMatched.Error()) {
|
|
t.Fatalf("error expected %v received %v", errIDCannotBeMatched, err)
|
|
}
|
|
|
|
updates = &Update{
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 2}},
|
|
}
|
|
err = d.DeleteBidAskByID(updates, false)
|
|
if !strings.Contains(err.Error(), errIDCannotBeMatched.Error()) {
|
|
t.Fatalf("error expected %v received %v", errIDCannotBeMatched, err)
|
|
}
|
|
|
|
updates = &Update{
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 2}},
|
|
}
|
|
err = d.DeleteBidAskByID(updates, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("error expected %v received %v", nil, err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateBidAskByID(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates := &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 1}},
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 2}},
|
|
}
|
|
err := d.UpdateBidAskByID(updates)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if ob.Asks[0].Amount != 2 || ob.Bids[0].Amount != 2 {
|
|
t.Fatalf("orderbook amounts not updated correctly")
|
|
}
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 666}},
|
|
}
|
|
// random unmatching IDs
|
|
err = d.UpdateBidAskByID(updates)
|
|
if !strings.Contains(err.Error(), errIDCannotBeMatched.Error()) {
|
|
t.Fatalf("error expected %v received %v", errIDCannotBeMatched, err)
|
|
}
|
|
|
|
updates = &Update{
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 69}},
|
|
}
|
|
err = d.UpdateBidAskByID(updates)
|
|
if !strings.Contains(err.Error(), errIDCannotBeMatched.Error()) {
|
|
t.Fatalf("error expected %v received %v", errIDCannotBeMatched, err)
|
|
}
|
|
}
|
|
|
|
func TestInsertBidAskByID(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates := &Update{
|
|
Asks: Items{{Price: 1337, Amount: 2, ID: 3}},
|
|
}
|
|
|
|
err := d.InsertBidAskByID(updates)
|
|
if !strings.Contains(err.Error(), errCollisionDetected.Error()) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errCollisionDetected)
|
|
}
|
|
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1337, Amount: 2, ID: 3}},
|
|
}
|
|
|
|
err = d.InsertBidAskByID(updates)
|
|
if !strings.Contains(err.Error(), errCollisionDetected.Error()) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errCollisionDetected)
|
|
}
|
|
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1338, Amount: 2, ID: 3}},
|
|
Asks: Items{{Price: 1336, Amount: 2, ID: 4}},
|
|
}
|
|
err = d.InsertBidAskByID(updates)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if len(ob.Asks) != 2 || len(ob.Bids) != 2 {
|
|
t.Fatalf("items not added correctly")
|
|
}
|
|
}
|
|
|
|
func TestUpdateInsertByID(t *testing.T) {
|
|
t.Parallel()
|
|
d := NewDepth(id)
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates := &Update{
|
|
Bids: Items{{Price: 1338, Amount: 0, ID: 3}},
|
|
Asks: Items{{Price: 1336, Amount: 2, ID: 4}},
|
|
}
|
|
err := d.UpdateInsertByID(updates)
|
|
if !strings.Contains(err.Error(), errAmountCannotBeLessOrEqualToZero.Error()) {
|
|
t.Fatalf("expected: %v but received: %v", errAmountCannotBeLessOrEqualToZero, err)
|
|
}
|
|
|
|
// Above will invalidate the book
|
|
_, err = d.Retrieve()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1338, Amount: 2, ID: 3}},
|
|
Asks: Items{{Price: 1336, Amount: 0, ID: 4}},
|
|
}
|
|
err = d.UpdateInsertByID(updates)
|
|
if !strings.Contains(err.Error(), errAmountCannotBeLessOrEqualToZero.Error()) {
|
|
t.Fatalf("expected: %v but received: %v", errAmountCannotBeLessOrEqualToZero, err)
|
|
}
|
|
|
|
// Above will invalidate the book
|
|
_, err = d.Retrieve()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.LoadSnapshot(Items{{Price: 1337, Amount: 1, ID: 1}}, Items{{Price: 1337, Amount: 10, ID: 2}}, 0, time.Time{}, false)
|
|
|
|
updates = &Update{
|
|
Bids: Items{{Price: 1338, Amount: 2, ID: 3}},
|
|
Asks: Items{{Price: 1336, Amount: 2, ID: 4}},
|
|
}
|
|
err = d.UpdateInsertByID(updates)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ob, err := d.Retrieve()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if len(ob.Asks) != 2 || len(ob.Bids) != 2 {
|
|
t.Fatalf("items not added correctly")
|
|
}
|
|
}
|
|
|
|
func TestAssignOptions(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
cp := currency.NewPair(currency.LINK, currency.BTC)
|
|
tn := time.Now()
|
|
d.AssignOptions(&Base{
|
|
Exchange: "test",
|
|
Pair: cp,
|
|
Asset: asset.Spot,
|
|
LastUpdated: tn,
|
|
LastUpdateID: 1337,
|
|
PriceDuplication: true,
|
|
IsFundingRate: true,
|
|
VerifyOrderbook: true,
|
|
RestSnapshot: true,
|
|
IDAlignment: true,
|
|
})
|
|
|
|
if d.exchange != "test" ||
|
|
d.pair != cp ||
|
|
d.asset != asset.Spot ||
|
|
d.lastUpdated != tn ||
|
|
d.lastUpdateID != 1337 ||
|
|
!d.priceDuplication ||
|
|
!d.isFundingRate ||
|
|
!d.VerifyOrderbook ||
|
|
!d.restSnapshot ||
|
|
!d.idAligned {
|
|
t.Fatalf("failed to set correctly")
|
|
}
|
|
}
|
|
|
|
func TestGetName(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
d.exchange = "test"
|
|
if d.GetName() != "test" {
|
|
t.Fatalf("failed to get correct value")
|
|
}
|
|
}
|
|
|
|
func TestIsRestSnapshot(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
d.restSnapshot = true
|
|
err := d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
_, err = d.IsRESTSnapshot()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.validationError = nil
|
|
b, err := d.IsRESTSnapshot()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !b {
|
|
t.Fatalf("received: '%v' but expected: '%v'", b, true)
|
|
}
|
|
}
|
|
|
|
func TestLastUpdateID(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
err := d.Invalidate(nil)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
_, err = d.LastUpdateID()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
d.validationError = nil
|
|
d.lastUpdateID = 1337
|
|
id, err := d.LastUpdateID()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if id != 1337 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", id, 1337)
|
|
}
|
|
}
|
|
|
|
func TestIsFundingRate(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
d.isFundingRate = true
|
|
if !d.IsFundingRate() {
|
|
t.Fatalf("failed to get correct value")
|
|
}
|
|
}
|
|
|
|
func TestPublish(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
if err := d.Invalidate(nil); !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
d.Publish()
|
|
d.validationError = nil
|
|
d.Publish()
|
|
}
|
|
|
|
func TestIsValid(t *testing.T) {
|
|
t.Parallel()
|
|
d := Depth{}
|
|
if !d.IsValid() {
|
|
t.Fatalf("received: '%v' but expected: '%v'", d.IsValid(), true)
|
|
}
|
|
if err := d.Invalidate(nil); !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
if d.IsValid() {
|
|
t.Fatalf("received: '%v' but expected: '%v'", d.IsValid(), false)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByNominalSlippage(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByNominalSlippage(10, 1355.5)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.HitTheBidsByNominalSlippage(10, 1355.5)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First tranche
|
|
amt, err := depth.HitTheBidsByNominalSlippage(0, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 1 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 2)
|
|
}
|
|
|
|
if amt.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 0)
|
|
}
|
|
|
|
if amt.StartPrice != 1336 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1336)
|
|
}
|
|
|
|
if amt.EndPrice != 1336 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1336)
|
|
}
|
|
|
|
if amt.FullBookSideConsumed {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt.FullBookSideConsumed, false)
|
|
}
|
|
|
|
// First and second price
|
|
amt, err = depth.HitTheBidsByNominalSlippage(0.037425149700598806, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 2 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 2)
|
|
}
|
|
|
|
if amt.NominalPercentage != 0.037425149700598806 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 0.037425149700598806)
|
|
}
|
|
|
|
if amt.StartPrice != 1336 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1336)
|
|
}
|
|
|
|
if amt.EndPrice != 1335 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1335)
|
|
}
|
|
|
|
if amt.FullBookSideConsumed {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt.FullBookSideConsumed, false)
|
|
}
|
|
|
|
// First and half of second tranche
|
|
amt, err = depth.HitTheBidsByNominalSlippage(0.02495009980039353, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 1.4999999999998295 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1.4999999999998295)
|
|
}
|
|
|
|
if amt.NominalPercentage != 0.02495009980039353 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 0.02495009980039353)
|
|
}
|
|
|
|
if amt.StartPrice != 1336 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1336)
|
|
}
|
|
|
|
if amt.EndPrice != 1335 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1335)
|
|
}
|
|
|
|
if amt.FullBookSideConsumed {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt.FullBookSideConsumed, false)
|
|
}
|
|
|
|
// All the way up to the last price
|
|
amt, err = depth.HitTheBidsByNominalSlippage(0.7110778443113772, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This exceeds the entire total base available - should be 20.
|
|
if amt.Sold != 20 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 20.00721336370539)
|
|
}
|
|
|
|
if amt.NominalPercentage != 0.7110778443113772 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 0.7110778443113772)
|
|
}
|
|
|
|
if amt.StartPrice != 1336 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1336)
|
|
}
|
|
|
|
if amt.EndPrice != 1317 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 1317)
|
|
}
|
|
|
|
if !amt.FullBookSideConsumed {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt.FullBookSideConsumed, true)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByNominalSlippageFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByNominalSlippageFromMid(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.HitTheBidsByNominalSlippageFromMid(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
// First price from mid point
|
|
amt, err := depth.HitTheBidsByNominalSlippageFromMid(0.03741114852226)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 1 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 1)
|
|
}
|
|
|
|
// All the way up to the last price from mid price
|
|
amt, err = depth.HitTheBidsByNominalSlippageFromMid(0.74822297044519)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This exceeds the entire total base available
|
|
if amt.Sold != 20 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 20)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByNominalSlippageFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByNominalSlippageFromBest(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.HitTheBidsByNominalSlippageFromBest(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
// First and second price from best bid
|
|
amt, err := depth.HitTheBidsByNominalSlippageFromBest(0.037425149700599)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 2 {
|
|
t.Fatalf("received: '%+v' but expected: '%+v'", amt, 2)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.HitTheBidsByNominalSlippageFromBest(0.71107784431138)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This exceeds the entire total base available
|
|
if amt.Sold != 20 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 20)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByNominalSlippage(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByNominalSlippage(10, 1355.5)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.LiftTheAsksByNominalSlippage(10, 1355.5)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price
|
|
amt, err := depth.LiftTheAsksByNominalSlippage(0.037397157816006, 1337)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 2675 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 2675)
|
|
}
|
|
|
|
// All the way up to the last price
|
|
amt, err = depth.LiftTheAsksByNominalSlippage(0.71054599850411, 1337)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 26930 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 26930)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByNominalSlippageFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByNominalSlippageFromMid(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.LiftTheAsksByNominalSlippageFromMid(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
// First price from mid point
|
|
amt, err := depth.LiftTheAsksByNominalSlippageFromMid(0.074822297044519)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 2675 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 2675)
|
|
}
|
|
|
|
// All the way up to the last price from mid price
|
|
amt, err = depth.LiftTheAsksByNominalSlippageFromMid(0.74822297044519)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This does not match the entire total quote available
|
|
if amt.Sold != 26930 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 26930)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByNominalSlippageFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByNominalSlippageFromBest(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.LiftTheAsksByNominalSlippageFromBest(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
// First and second price from best bid
|
|
amt, err := depth.LiftTheAsksByNominalSlippageFromBest(0.037397157816006)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 2675 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 2675)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.LiftTheAsksByNominalSlippageFromBest(0.71054599850411)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This does not match the entire total quote available
|
|
if amt.Sold != 26930 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 26930)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByImpactSlippage(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByImpactSlippage(0.7485029940119761, 1336)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from best bid - price level target 1326 (which should be kept)
|
|
amt, err := depth.HitTheBidsByImpactSlippage(0.7485029940119761, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 10 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 10)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.HitTheBidsByImpactSlippage(1.4221556886227544, 1336)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This does not match the entire total quote available - should be 26930.
|
|
if amt.Sold != 19 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 19)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByImpactSlippageFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByImpactSlippageFromMid(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.HitTheBidsByImpactSlippageFromMid(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from mid - price level target 1326 (which should be kept)
|
|
amt, err := depth.HitTheBidsByImpactSlippageFromMid(0.7485029940119761)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 10 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 10)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.HitTheBidsByImpactSlippageFromMid(1.4221556886227544)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 19 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 19)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsByImpactSlippageFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsByImpactSlippageFromBest(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.HitTheBidsByImpactSlippageFromBest(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from mid - price level target 1326 (which should be kept)
|
|
amt, err := depth.HitTheBidsByImpactSlippageFromBest(0.7485029940119761)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 10 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 10)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.HitTheBidsByImpactSlippageFromBest(1.4221556886227544)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 19 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 19)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByImpactSlippage(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByImpactSlippage(0.7479431563201197, 1337)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from best bid - price level target 1326 (which should be kept)
|
|
amt, err := depth.LiftTheAsksByImpactSlippage(0.7479431563201197, 1337)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 13415 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 13415)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.LiftTheAsksByImpactSlippage(1.4210919970082274, 1337)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 25574 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 25574)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByImpactSlippageFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByImpactSlippageFromMid(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksByImpactSlippageFromMid(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from mid - price level target 1326 (which should be kept)
|
|
amt, err := depth.LiftTheAsksByImpactSlippageFromMid(0.7485029940119761)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 13415 {
|
|
t.Fatalf("received: '%+v' but expected: '%v'", amt, 13415)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.LiftTheAsksByImpactSlippageFromMid(1.4221556886227544)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 25574 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 25574)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksByImpactSlippageFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksByImpactSlippageFromBest(10)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksByImpactSlippageFromBest(10)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
// First and second price from mid - price level target 1326 (which should be kept)
|
|
amt, err := depth.LiftTheAsksByImpactSlippageFromBest(0.7479431563201197)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if amt.Sold != 13415 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 13415)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
amt, err = depth.LiftTheAsksByImpactSlippageFromBest(1.4210919970082274)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
// This goes to price 1356, it will not count that tranches' volume as it
|
|
// is needed to sustain the slippage.
|
|
if amt.Sold != 25574 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", amt, 25574)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBids(t *testing.T) {
|
|
t.Parallel()
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBids(20.1, 1336, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBids(1, 1336, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07485029940119761 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07485029940119761)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBids(19.5, 1336, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.692845079072617 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.692845079072617)
|
|
}
|
|
if mov.ImpactPercentage != 1.4221556886227544 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4221556886227544)
|
|
}
|
|
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBids(20, 1336, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7110778443113772 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7110778443113772)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBids_QuotationRequired(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBids(26531, 1336, true)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBids(26531, 1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBids(1336, 1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07485029940119761 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07485029940119761)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBids(25871.5, 1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.692845079072617 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.692845079072617)
|
|
}
|
|
if mov.ImpactPercentage != 1.4221556886227544 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4221556886227544)
|
|
}
|
|
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBids(26530, 1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7110778443113772 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7110778443113772)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsFromMid(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.HitTheBidsFromMid(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBidsFromMid(20.1, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromMid(1, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.03741114852225963 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.03741114852225963)
|
|
}
|
|
|
|
if mov.ImpactPercentage != 0.11223344556677892 { // mid price 1336.5 -> 1335
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.11223344556677892)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromMid(19.5, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7299970262933156 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7299970262933156)
|
|
}
|
|
if mov.ImpactPercentage != 1.4590347923681257 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4590347923681257)
|
|
}
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBidsFromMid(20, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7482229704451926 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7482229704451926)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsFromMid_QuotationRequired(t *testing.T) {
|
|
t.Parallel()
|
|
depth := NewDepth(id)
|
|
_, err := depth.HitTheBidsFromMid(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBidsFromMid(26531, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromMid(1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.03741114852225963 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.03741114852225963)
|
|
}
|
|
|
|
if mov.ImpactPercentage != 0.11223344556677892 { // mid price 1336.5 -> 1335
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.11223344556677892)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromMid(25871.5, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7299970262933156 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7299970262933156)
|
|
}
|
|
if mov.ImpactPercentage != 1.4590347923681257 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4590347923681257)
|
|
}
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBidsFromMid(26530, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7482229704451926 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7482229704451926)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
depth := NewDepth(id)
|
|
_, err := depth.HitTheBidsFromBest(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBidsFromBest(20.1, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromBest(1, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07485029940119761 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07485029940119761)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromBest(19.5, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.692845079072617 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.692845079072617)
|
|
}
|
|
if mov.ImpactPercentage != 1.4221556886227544 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4221556886227544)
|
|
}
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBidsFromBest(20, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7110778443113772 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7110778443113772)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestHitTheBidsFromBest_QuotationRequired(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().HitTheBidsFromBest(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.HitTheBidsFromBest(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.HitTheBidsFromBest(26531, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromBest(1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07485029940119761 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07485029940119761)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.HitTheBidsFromBest(25871.5, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.692845079072617 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.692845079072617)
|
|
}
|
|
if mov.ImpactPercentage != 1.4221556886227544 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4221556886227544)
|
|
}
|
|
if mov.SlippageCost != 180.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 180.5)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.HitTheBidsFromBest(26530, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7110778443113772 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7110778443113772)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsks(t *testing.T) {
|
|
t.Parallel()
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsks(26931, 1337, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsks(1337, 1337, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07479431563201197 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07479431563201197)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsks(26900, 1337, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7097591258590459 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7097591258590459)
|
|
}
|
|
if mov.ImpactPercentage != 1.4210919970082274 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4210919970082274)
|
|
}
|
|
if mov.SlippageCost != 189.57964601770072 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.57964601770072)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsks(26930, 1336, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7859281437125748 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7859281437125748)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsks_BaseRequired(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsks(21, 1337, true)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsks(21, 1337, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsks(1, 1337, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07479431563201197 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07479431563201197)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsks(19.97787610619469, 1337, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7097591258590288 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7097591258590288)
|
|
}
|
|
if mov.ImpactPercentage != 1.4210919970082274 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4210919970082274)
|
|
}
|
|
if mov.SlippageCost != 189.5796460176971 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.5796460176971)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsks(20, 1336, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7859281437125748 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7859281437125748)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksFromMid(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksFromMid(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksFromMid(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsksFromMid(26931, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromMid(1337, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.03741114852225963 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.03741114852225963)
|
|
}
|
|
if mov.ImpactPercentage != 0.11223344556677892 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.11223344556677892)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromMid(26900, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.747435803422031 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.747435803422031)
|
|
}
|
|
if mov.ImpactPercentage != 1.4590347923681257 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4590347923681257)
|
|
}
|
|
if mov.SlippageCost != 189.57964601770072 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.57964601770072)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsksFromMid(26930, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7482229704451926 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7482229704451926)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksFromMid_BaseRequired(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksFromMid(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksFromMid(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsksFromMid(21, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromMid(1, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.03741114852225963 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.03741114852225963)
|
|
}
|
|
if mov.ImpactPercentage != 0.11223344556677892 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.11223344556677892)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromMid(19.97787610619469, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7474358034220139 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7474358034220139)
|
|
}
|
|
if mov.ImpactPercentage != 1.4590347923681257 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4590347923681257)
|
|
}
|
|
if mov.SlippageCost != 189.5796460176971 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.5796460176971)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsksFromMid(20, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7482229704451926 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7482229704451926)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksFromBest(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksFromBest(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksFromBest(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsksFromBest(26931, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromBest(1337, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07479431563201197 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07479431563201197)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromBest(26900, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7097591258590459 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7097591258590459)
|
|
}
|
|
if mov.ImpactPercentage != 1.4210919970082274 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4210919970082274)
|
|
}
|
|
if mov.SlippageCost != 189.57964601770072 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.57964601770072)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsksFromBest(26930, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7105459985041137 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7105459985041137)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestLiftTheAsksFromBest_BaseRequired(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().LiftTheAsksFromBest(10, false)
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.LiftTheAsksFromBest(10, false)
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mov, err := depth.LiftTheAsksFromBest(21, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if !mov.FullBookSideConsumed {
|
|
t.Fatal("entire side should be consumed by this value")
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromBest(1, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0)
|
|
}
|
|
if mov.ImpactPercentage != 0.07479431563201197 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 0.07479431563201197)
|
|
}
|
|
if mov.SlippageCost != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 0)
|
|
}
|
|
|
|
mov, err = depth.LiftTheAsksFromBest(19.97787610619469, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
if mov.NominalPercentage != 0.7097591258590288 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7097591258590288)
|
|
}
|
|
if mov.ImpactPercentage != 1.4210919970082274 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, 1.4210919970082274)
|
|
}
|
|
if mov.SlippageCost != 189.5796460176971 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 189.5796460176971)
|
|
}
|
|
|
|
// All the way up to the last price from best bid price
|
|
mov, err = depth.LiftTheAsksFromBest(20, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mov.NominalPercentage != 0.7105459985041137 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.NominalPercentage, 0.7105459985041137)
|
|
}
|
|
if mov.ImpactPercentage != FullLiquidityExhaustedPercentage {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.ImpactPercentage, FullLiquidityExhaustedPercentage)
|
|
}
|
|
if mov.SlippageCost != 190 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mov.SlippageCost, 190)
|
|
}
|
|
}
|
|
|
|
func TestGetMidPrice_Depth(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().GetMidPrice()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.GetMidPrice()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mid, err := depth.GetMidPrice()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mid != 1336.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mid, 1336.5)
|
|
}
|
|
}
|
|
|
|
func TestGetMidPriceNoLock_Depth(t *testing.T) {
|
|
t.Parallel()
|
|
depth := NewDepth(id)
|
|
_, err := depth.getMidPriceNoLock()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, nil, 0, time.Time{}, true)
|
|
_, err = depth.getMidPriceNoLock()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mid, err := depth.getMidPriceNoLock()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if mid != 1336.5 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mid, 1336.5)
|
|
}
|
|
}
|
|
|
|
func TestGetBestBidASk_Depth(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().GetBestBid()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
_, err = getInvalidDepth().GetBestAsk()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
_, err = depth.GetBestBid()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
_, err = depth.GetBestAsk()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
mid, err := depth.GetBestBid()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
if mid != 1336 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mid, 1336)
|
|
}
|
|
mid, err = depth.GetBestAsk()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
if mid != 1337 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", mid, 1337)
|
|
}
|
|
}
|
|
|
|
func TestGetSpreadAmount(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().GetSpreadAmount()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.GetSpreadAmount()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(nil, ask, 0, time.Time{}, true)
|
|
|
|
_, err = depth.GetSpreadAmount()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
spread, err := depth.GetSpreadAmount()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if spread != 1 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", spread, 1)
|
|
}
|
|
}
|
|
|
|
func TestGetSpreadPercentage(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().GetSpreadPercentage()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.GetSpreadPercentage()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(nil, ask, 0, time.Time{}, true)
|
|
|
|
_, err = depth.GetSpreadPercentage()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
spread, err := depth.GetSpreadPercentage()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if spread != 0.07479431563201197 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", spread, 0.07479431563201197)
|
|
}
|
|
}
|
|
|
|
func TestGetImbalance_Depth(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := getInvalidDepth().GetImbalance()
|
|
if !errors.Is(err, ErrOrderbookInvalid) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, ErrOrderbookInvalid)
|
|
}
|
|
|
|
depth := NewDepth(id)
|
|
|
|
_, err = depth.GetImbalance()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(nil, ask, 0, time.Time{}, true)
|
|
|
|
_, err = depth.GetImbalance()
|
|
if !errors.Is(err, errNoLiquidity) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, errNoLiquidity)
|
|
}
|
|
|
|
depth.LoadSnapshot(bid, ask, 0, time.Time{}, true)
|
|
|
|
imbalance, err := depth.GetImbalance()
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
if imbalance != 0 {
|
|
t.Fatalf("received: '%v' but expected: '%v'", imbalance, 0)
|
|
}
|
|
}
|
|
|
|
func getInvalidDepth() *Depth {
|
|
depth := NewDepth(id)
|
|
_ = depth.Invalidate(errors.New("invalid reasoning"))
|
|
return depth
|
|
}
|