mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
orders: Add AdjustBaseAmount (#1181)
* orders: Add AdjustBaseAmount method that alerts if non-fatal change occurs exchange side, adjust BTCM * glorious: nits * glorious: nits * thrasher: nits * Update exchanges/btcmarkets/btcmarkets_wrapper.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update exchanges/btcmarkets/btcmarkets_wrapper.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher: nits and whoopsie * orders_test: fix --------- Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -592,7 +592,29 @@ func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (*order.S
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.DeriveSubmitResponse(tempResp.OrderID)
|
||||
|
||||
submitResp, err := s.DeriveSubmitResponse(tempResp.OrderID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tempResp.Amount != 0 {
|
||||
err = submitResp.AdjustBaseAmount(tempResp.Amount)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s base amount conversion error: %s\n", b.Name, submitResp.OrderID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if tempResp.TargetAmount != 0 {
|
||||
err = submitResp.AdjustQuoteAmount(tempResp.TargetAmount)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "Exchange %s: OrderID: %s quote amount conversion error: %s\n", b.Name, submitResp.OrderID, err)
|
||||
}
|
||||
}
|
||||
// With market orders the price is optional, so we can set it to the
|
||||
// actual price that was filled.
|
||||
submitResp.Price = tempResp.Price
|
||||
return submitResp, nil
|
||||
}
|
||||
|
||||
// ModifyOrder will allow of changing orderbook placement and limit to
|
||||
|
||||
@@ -1260,11 +1260,11 @@ func TestUpdateOrderFromDetail(t *testing.T) {
|
||||
|
||||
func TestClassificationError_Error(t *testing.T) {
|
||||
class := ClassificationError{OrderID: "1337", Exchange: "test", Err: errors.New("test error")}
|
||||
if class.Error() != "test - OrderID: 1337 classification error: test error" {
|
||||
if class.Error() != "Exchange test: OrderID: 1337 classification error: test error" {
|
||||
t.Fatal("unexpected output")
|
||||
}
|
||||
class.OrderID = ""
|
||||
if class.Error() != "test - classification error: test error" {
|
||||
if class.Error() != "Exchange test: classification error: test error" {
|
||||
t.Fatal("unexpected output")
|
||||
}
|
||||
}
|
||||
@@ -1959,3 +1959,75 @@ func TestIsValidOrderSubmissionSide(t *testing.T) {
|
||||
t.Error("expected false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustBaseAmount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var s *SubmitResponse
|
||||
err := s.AdjustBaseAmount(0)
|
||||
if !errors.Is(err, errOrderSubmitResponseIsNil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errOrderSubmitResponseIsNil)
|
||||
}
|
||||
|
||||
s = &SubmitResponse{}
|
||||
err = s.AdjustBaseAmount(0)
|
||||
if !errors.Is(err, errAmountIsZero) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errAmountIsZero)
|
||||
}
|
||||
|
||||
s.Amount = 1.7777777777
|
||||
err = s.AdjustBaseAmount(1.7777777777)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if s.Amount != 1.7777777777 {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", s.Amount, 1.7777777777)
|
||||
}
|
||||
|
||||
s.Amount = 1.7777777777
|
||||
err = s.AdjustBaseAmount(1.777)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if s.Amount != 1.777 {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", s.Amount, 1.777)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdjustQuoteAmount(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var s *SubmitResponse
|
||||
err := s.AdjustQuoteAmount(0)
|
||||
if !errors.Is(err, errOrderSubmitResponseIsNil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errOrderSubmitResponseIsNil)
|
||||
}
|
||||
|
||||
s = &SubmitResponse{}
|
||||
err = s.AdjustQuoteAmount(0)
|
||||
if !errors.Is(err, errAmountIsZero) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, errAmountIsZero)
|
||||
}
|
||||
|
||||
s.QuoteAmount = 5.222222222222
|
||||
err = s.AdjustQuoteAmount(5.222222222222)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if s.QuoteAmount != 5.222222222222 {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", s.Amount, 5.222222222222)
|
||||
}
|
||||
|
||||
s.QuoteAmount = 5.222222222222
|
||||
err = s.AdjustQuoteAmount(5.22222222)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
|
||||
if s.QuoteAmount != 5.22222222 {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", s.Amount, 5.22222222)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ var (
|
||||
errOrderSubmitIsNil = errors.New("order submit is nil")
|
||||
errOrderSubmitResponseIsNil = errors.New("order submit response is nil")
|
||||
errOrderDetailIsNil = errors.New("order detail is nil")
|
||||
errAmountIsZero = errors.New("amount is zero")
|
||||
)
|
||||
|
||||
// IsValidOrderSubmissionSide validates that the order side is a valid submission direction
|
||||
@@ -475,6 +476,64 @@ func (s *Submit) DeriveSubmitResponse(orderID string) (*SubmitResponse, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AdjustBaseAmount will adjust the base amount of a submit response if the
|
||||
// exchange has modified the amount. This is usually due to decimal place
|
||||
// restrictions or rounding. This will return an error if the amount is zero
|
||||
// or the submit response is nil.
|
||||
func (s *SubmitResponse) AdjustBaseAmount(a float64) error {
|
||||
if s == nil {
|
||||
return errOrderSubmitResponseIsNil
|
||||
}
|
||||
|
||||
if a <= 0 {
|
||||
return errAmountIsZero
|
||||
}
|
||||
|
||||
if s.Amount == a {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Warning because amounts should conform to exchange requirements prior to
|
||||
// call but this is not fatal.
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s: has adjusted OrderID: %s requested base amount from %v to %v",
|
||||
s.Exchange,
|
||||
s.OrderID,
|
||||
s.Amount,
|
||||
a)
|
||||
|
||||
s.Amount = a
|
||||
return nil
|
||||
}
|
||||
|
||||
// AdjustQuoteAmount will adjust the quote amount of a submit response if the
|
||||
// exchange has modified the amount. This is usually due to decimal place
|
||||
// restrictions or rounding. This will return an error if the amount is zero
|
||||
// or the submit response is nil.
|
||||
func (s *SubmitResponse) AdjustQuoteAmount(a float64) error {
|
||||
if s == nil {
|
||||
return errOrderSubmitResponseIsNil
|
||||
}
|
||||
|
||||
if a <= 0 {
|
||||
return errAmountIsZero
|
||||
}
|
||||
|
||||
if s.QuoteAmount == a {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Warning because amounts should conform to exchange requirements prior to
|
||||
// call but this is not fatal.
|
||||
log.Warnf(log.ExchangeSys, "Exchange %s: has adjusted OrderID: %s requested quote amount from %v to %v",
|
||||
s.Exchange,
|
||||
s.OrderID,
|
||||
s.Amount,
|
||||
a)
|
||||
|
||||
s.QuoteAmount = a
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeriveDetail will construct an order detail when a successful submission
|
||||
// has occurred. Has an optional parameter field internal uuid for internal
|
||||
// management.
|
||||
@@ -1069,12 +1128,12 @@ func StringToOrderStatus(status string) (Status, error) {
|
||||
|
||||
func (o *ClassificationError) Error() string {
|
||||
if o.OrderID != "" {
|
||||
return fmt.Sprintf("%s - OrderID: %s classification error: %v",
|
||||
return fmt.Sprintf("Exchange %s: OrderID: %s classification error: %v",
|
||||
o.Exchange,
|
||||
o.OrderID,
|
||||
o.Err)
|
||||
}
|
||||
return fmt.Sprintf("%s - classification error: %v",
|
||||
return fmt.Sprintf("Exchange %s: classification error: %v",
|
||||
o.Exchange,
|
||||
o.Err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user