exchanges: Order types update (#1850)

* Added TimeInForce type and updated related files

* Linter issue fix and minor coinbasepro type update

* Bitrex consts update

* added unit test and minor changes in bittrex

* Unit tests update

* Fix minor linter issues

* Update TestStringToTimeInForce unit test

* fix conflict with gateio timeInForce

* Update order tests

* Complete updating the order unit tests

* update kucoin and deribit wrapper to match the time in force change

* fix time-in-force related test errors

* linter issue fix

* time in force constants, functions and unit tests update

* shift tif policies to TimeInForce

* Update time-in-force, related functions, and unit tests

* fix linter issue and time-in-force processing

* added a good till crossing tif value

* order type fix and fix related tim-in-force entries

* update time-in-force unmarshaling and unit test

* update order type to support time-in-force and hybrid order type representation

* added tests for type and time-in-force check from order type

* fix time-in-force error in gateio

* fix minor unit test issues

* linter issue fix

* update based on review comments

* add unit test and fix missing issues

* minor fix and added benchmark unit test

* change GTT to GTC for limit

* fix linter issue

* linter issues fix

* update order types declaration and handling by endpoints

* added time-in-force value to place order param

* fix minor issues based on review comment and move tif code to separate files

* update on exchanges linked to time-in-force

* resolve missing review comments

* minor linter issues fix

* added time-in-force handler and update timeInForce parametered endpoint

* minor fixes based on review

* nits fix

* update based on review

* linter fix

* rm getTimeInForce func and minor change to time-in-force

* minor change

* update based on review comments

* wrappers and time-in-force calling approach

* minor change

* update gateio string to timeInForce conversion and unit test

* fix types to string conversion

* fix build errors

* update on order types handling and unit tests

* fix linter issue

* order type unit tests update

* order types string as constant replacement and unit tests update

* update order type-string functions unit test
This commit is contained in:
Samuael A.
2025-06-12 08:39:17 +03:00
committed by GitHub
parent d5ba674fc4
commit a8a3bc4ee2
9 changed files with 265 additions and 148 deletions

View File

@@ -297,6 +297,33 @@ func TestTitle(t *testing.T) {
require.Equal(t, "Limit", orderType.Title())
}
func TestOrderIs(t *testing.T) {
t.Parallel()
orderComparisonList := []struct {
Type Type
Targets []Type
}{
{Type: Limit | TakeProfit, Targets: []Type{TakeProfit, Limit}},
{Type: IOS, Targets: []Type{IOS}},
{Type: Stop, Targets: []Type{Stop}},
{Type: AnyType, Targets: []Type{AnyType}},
{Type: StopLimit, Targets: []Type{Stop, Limit}},
{Type: TakeProfit, Targets: []Type{TakeProfit}},
{Type: StopMarket, Targets: []Type{Stop, Market}},
{Type: TrailingStop, Targets: []Type{TrailingStop}},
{Type: UnknownType | Limit, Targets: []Type{Limit}},
{Type: TakeProfitMarket, Targets: []Type{TakeProfit, Market}},
}
for _, oType := range orderComparisonList {
t.Run(oType.Type.String(), func(t *testing.T) {
t.Parallel()
for _, target := range oType.Targets {
assert.Truef(t, oType.Type.Is(target), "expected %v, got %q", target, oType.Type.String())
}
})
}
}
func TestOrderTypes(t *testing.T) {
t.Parallel()
var orderType Type
@@ -305,6 +332,41 @@ func TestOrderTypes(t *testing.T) {
assert.Equal(t, "Unknown", orderType.Title())
}
func TestOrderTypeToString(t *testing.T) {
t.Parallel()
orderToToStringsList := []struct {
OrderType Type
String string
}{
{StopMarket, "STOP MARKET"},
{StopLimit, "STOP LIMIT"},
{Limit, "LIMIT"},
{Market, "MARKET"},
{Stop, "STOP"},
{ConditionalStop, "CONDITIONAL"},
{TWAP, "TWAP"},
{Chase, "CHASE"},
{TakeProfit, "TAKE PROFIT"},
{TakeProfitMarket, "TAKE PROFIT MARKET"},
{TrailingStop, "TRAILING_STOP"},
{IOS, "IOS"},
{Liquidation, "LIQUIDATION"},
{Trigger, "TRIGGER"},
{OCO, "OCO"},
{OptimalLimit, "OPTIMAL_LIMIT"},
{MarketMakerProtection, "MMP"},
{AnyType, "ANY"},
{UnknownType | Limit, "LIMIT"},
{StopMarket | ConditionalStop, "UNKNOWN"},
}
for _, tt := range orderToToStringsList {
t.Run(tt.String, func(t *testing.T) {
t.Parallel()
assert.Equal(t, tt.String, tt.OrderType.String())
})
}
}
func TestInferCostsAndTimes(t *testing.T) {
t.Parallel()
var detail Detail
@@ -736,6 +798,7 @@ func BenchmarkStringToOrderSide(b *testing.B) {
}
func TestStringToOrderType(t *testing.T) {
t.Parallel()
cases := []struct {
in string
out Type
@@ -766,14 +829,12 @@ func TestStringToOrderType(t *testing.T) {
{"conDitiOnal", ConditionalStop, nil},
{"oCo", OCO, nil},
{"mMp", MarketMakerProtection, nil},
{"Mmp_And_Post_oNly", MarketMakerProtectionAndPostOnly, nil},
{"tWaP", TWAP, nil},
{"TWAP", TWAP, nil},
{"woahMan", UnknownType, errUnrecognisedOrderType},
{"chase", Chase, nil},
{"MOVE_ORDER_STOP", TrailingStop, nil},
{"mOVe_OrdeR_StoP", TrailingStop, nil},
{"optimal_limit_IoC", OptimalLimitIOC, nil},
{"Stop_market", StopMarket, nil},
{"liquidation", Liquidation, nil},
{"LiQuidation", Liquidation, nil},
@@ -781,10 +842,13 @@ func TestStringToOrderType(t *testing.T) {
{"Take ProfIt", TakeProfit, nil},
{"TAKE PROFIT MARkEt", TakeProfitMarket, nil},
{"TAKE_PROFIT_MARkEt", TakeProfitMarket, nil},
{"optimal_limit", OptimalLimit, nil},
{"OPTIMAL_LIMIT", OptimalLimit, nil},
}
for i := range cases {
testData := &cases[i]
t.Run(testData.in, func(t *testing.T) {
t.Parallel()
out, err := StringToOrderType(testData.in)
require.ErrorIs(t, err, testData.err)
assert.Equal(t, testData.out, out)

View File

@@ -348,7 +348,12 @@ const (
)
// Type enforces a standard for order types across the code base
type Type uint32
type Type uint64
// Is checks to see if the Type contains the Type cmp
func (t Type) Is(cmp Type) bool {
return cmp != 0 && t&cmp == cmp
}
// Defined package order types
const (
@@ -356,22 +361,45 @@ const (
Limit Type = 1 << iota
Market
Stop
StopLimit
StopMarket
TakeProfit
TakeProfitMarket
TrailingStop
IOS
AnyType
Liquidation
Trigger
OptimalLimitIOC
OCO // One-cancels-the-other order
ConditionalStop // One-way stop order
MarketMakerProtection // market-maker-protection used with portfolio margin mode. See https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
MarketMakerProtectionAndPostOnly // market-maker-protection and post-only mode. Used in Okx exchange orders.
TWAP // time-weighted average price.
Chase // chase order. See https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-place-algo-order
OCO // One-cancels-the-other order
ConditionalStop // One-way stop order
TWAP // time-weighted average price
Chase // chase limit order
OptimalLimit
MarketMakerProtection
// Hybrid order types
StopLimit = Stop | Limit
StopMarket = Stop | Market
TakeProfitMarket = TakeProfit | Market
)
// order-type string representations
const (
orderStopMarket = "STOP MARKET"
orderStopLimit = "STOP LIMIT"
orderLimit = "LIMIT"
orderMarket = "MARKET"
orderStop = "STOP"
orderConditionalStop = "CONDITIONAL"
orderTWAP = "TWAP"
orderChase = "CHASE"
orderTakeProfit = "TAKE PROFIT"
orderTakeProfitMarket = "TAKE PROFIT MARKET"
orderTrailingStop = "TRAILING_STOP"
orderIOS = "IOS"
orderLiquidation = "LIQUIDATION"
orderTrigger = "TRIGGER"
orderOCO = "OCO"
orderOptimalLimit = "OPTIMAL_LIMIT"
orderMarketMakerProtection = "MMP"
orderAnyType = "ANY"
)
// Side enforces a standard for order sides across the code base

View File

@@ -667,44 +667,42 @@ func (d *Detail) DeriveCancel() (*Cancel, error) {
// String implements the stringer interface
func (t Type) String() string {
switch t {
case AnyType:
return "ANY"
case Limit:
return "LIMIT"
case Market:
return "MARKET"
case Stop:
return "STOP"
case ConditionalStop:
return "CONDITIONAL"
case MarketMakerProtection:
return "MMP"
case MarketMakerProtectionAndPostOnly:
return "MMP_AND_POST_ONLY"
case TWAP:
return "TWAP"
case Chase:
return "CHASE"
case StopLimit:
return "STOP LIMIT"
case StopMarket:
return "STOP MARKET"
return orderStopMarket
case StopLimit:
return orderStopLimit
case Limit:
return orderLimit
case Market:
return orderMarket
case Stop:
return orderStop
case ConditionalStop:
return orderConditionalStop
case TWAP:
return orderTWAP
case Chase:
return orderChase
case TakeProfit:
return "TAKE PROFIT"
return orderTakeProfit
case TakeProfitMarket:
return "TAKE PROFIT MARKET"
return orderTakeProfitMarket
case TrailingStop:
return "TRAILING_STOP"
return orderTrailingStop
case IOS:
return "IOS"
return orderIOS
case Liquidation:
return "LIQUIDATION"
return orderLiquidation
case Trigger:
return "TRIGGER"
case OptimalLimitIOC:
return "OPTIMAL_LIMIT_IOC"
return orderTrigger
case OCO:
return "OCO"
return orderOCO
case OptimalLimit:
return orderOptimalLimit
case MarketMakerProtection:
return orderMarketMakerProtection
case AnyType:
return orderAnyType
default:
return "UNKNOWN"
}
@@ -1102,43 +1100,41 @@ func (s Side) MarshalJSON() ([]byte, error) {
func StringToOrderType(oType string) (Type, error) {
oType = strings.ToUpper(oType)
switch oType {
case Limit.String(), "EXCHANGE LIMIT":
case orderLimit, "EXCHANGE LIMIT":
return Limit, nil
case Market.String(), "EXCHANGE MARKET":
case orderMarket, "EXCHANGE MARKET":
return Market, nil
case Stop.String(), "STOP LOSS", "STOP_LOSS", "EXCHANGE STOP":
case orderStop, "STOP LOSS", "STOP_LOSS", "EXCHANGE STOP":
return Stop, nil
case StopLimit.String(), "EXCHANGE STOP LIMIT", "STOP_LIMIT":
case orderStopLimit, "EXCHANGE STOP LIMIT", "STOP_LIMIT":
return StopLimit, nil
case StopMarket.String(), "STOP_MARKET":
case orderStopMarket, "STOP_MARKET":
return StopMarket, nil
case TrailingStop.String(), "TRAILING STOP", "EXCHANGE TRAILING STOP", "MOVE_ORDER_STOP":
case orderTrailingStop, "TRAILING STOP", "EXCHANGE TRAILING STOP", "MOVE_ORDER_STOP":
return TrailingStop, nil
case IOS.String():
case orderIOS:
return IOS, nil
case AnyType.String():
case orderAnyType:
return AnyType, nil
case Trigger.String():
case orderTrigger:
return Trigger, nil
case OptimalLimitIOC.String():
return OptimalLimitIOC, nil
case OCO.String():
case orderOptimalLimit:
return OptimalLimit, nil
case orderOCO:
return OCO, nil
case ConditionalStop.String():
case orderConditionalStop:
return ConditionalStop, nil
case MarketMakerProtection.String():
case orderMarketMakerProtection:
return MarketMakerProtection, nil
case MarketMakerProtectionAndPostOnly.String():
return MarketMakerProtectionAndPostOnly, nil
case TWAP.String():
case orderTWAP:
return TWAP, nil
case Chase.String():
case orderChase:
return Chase, nil
case TakeProfitMarket.String(), "TAKE_PROFIT_MARKET":
case orderTakeProfitMarket, "TAKE_PROFIT_MARKET":
return TakeProfitMarket, nil
case TakeProfit.String(), "TAKE_PROFIT":
case orderTakeProfit, "TAKE_PROFIT":
return TakeProfit, nil
case Liquidation.String():
case orderLiquidation:
return Liquidation, nil
default:
return UnknownType, fmt.Errorf("'%v' %w", oType, errUnrecognisedOrderType)