Skip to content

Commit 4dbb67c

Browse files
authored
feat: support algo trades (#688)
* feat: support algo trades * add static tests * increase timeout * lint * increase timeout * increase timeout * copilot changes
1 parent 210422c commit 4dbb67c

File tree

6 files changed

+855
-13
lines changed

6 files changed

+855
-13
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"build": "rm -rf dist && babel src -d dist",
2222
"prepare": "npm run build",
2323
"test": "npm run test:ava && npm run test:browser",
24-
"test:ava": "ava --timeout=10s -v",
24+
"test:ava": "ava --timeout=90s -v",
2525
"test:browser": "node test/browser/browser-test-runner.mjs && ava test/browser/crypto-browser-playwright.js test/browser/websocket-browser.test.js --timeout=15s -v",
2626
"test:browser:signature": "node test/browser/browser-test-runner.mjs",
2727
"test:browser:websocket": "ava test/browser/websocket-browser.test.js --timeout=15s -v",

src/http-client.js

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -570,15 +570,105 @@ export default opts => {
570570
futuresFundingRate: payload =>
571571
checkParams('fundingRate', payload, ['symbol']) &&
572572
pubCall('/fapi/v1/fundingRate', payload),
573-
futuresOrder: payload => order(privCall, payload, '/fapi/v1/order'),
573+
futuresOrder: payload => {
574+
// Check if this is a conditional order type that should be routed to algo endpoint
575+
const orderType = payload?.type?.toUpperCase()
576+
const conditionalTypes = [
577+
'STOP',
578+
'STOP_MARKET',
579+
'TAKE_PROFIT',
580+
'TAKE_PROFIT_MARKET',
581+
'TRAILING_STOP_MARKET',
582+
]
583+
584+
if (orderType && conditionalTypes.includes(orderType)) {
585+
// Route to algo order endpoint
586+
const algoPayload = { ...payload }
587+
if (!algoPayload.clientAlgoId) {
588+
algoPayload.clientAlgoId = futuresP()
589+
}
590+
delete algoPayload.newClientOrderId
591+
algoPayload.algoType = 'CONDITIONAL'
592+
if (algoPayload.stopPrice && !algoPayload.triggerPrice) {
593+
algoPayload.triggerPrice = algoPayload.stopPrice
594+
delete algoPayload.stopPrice
595+
}
596+
return privCall('/fapi/v1/algoOrder', algoPayload, 'POST')
597+
}
598+
// Use regular order endpoint
599+
return order(privCall, payload, '/fapi/v1/order')
600+
},
574601
futuresBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'POST'),
575-
futuresGetOrder: payload => privCall('/fapi/v1/order', payload),
576-
futuresCancelOrder: payload => privCall('/fapi/v1/order', payload, 'DELETE'),
577-
futuresCancelAllOpenOrders: payload =>
578-
privCall('/fapi/v1/allOpenOrders', payload, 'DELETE'),
602+
futuresGetOrder: payload => {
603+
// Check if this is a request for a conditional/algo order
604+
const isConditional = payload?.conditional
605+
const hasAlgoId = payload?.algoId || payload?.clientAlgoId
606+
let payloadCopy = payload
607+
if (payload && 'conditional' in payload) {
608+
payloadCopy = { ...payload }
609+
delete payloadCopy.conditional
610+
}
611+
612+
if (isConditional || hasAlgoId) {
613+
return privCall('/fapi/v1/algoOrder', payloadCopy)
614+
}
615+
return privCall('/fapi/v1/order', payloadCopy)
616+
},
617+
futuresCancelOrder: payload => {
618+
// Check if this is a request for a conditional/algo order
619+
const isConditional = payload?.conditional
620+
const hasAlgoId = payload?.algoId || payload?.clientAlgoId
621+
let payloadCopy = payload
622+
if (payload && 'conditional' in payload) {
623+
payloadCopy = { ...payload }
624+
delete payloadCopy.conditional
625+
}
626+
627+
if (isConditional || hasAlgoId) {
628+
return privCall('/fapi/v1/algoOrder', payloadCopy, 'DELETE')
629+
}
630+
return privCall('/fapi/v1/order', payloadCopy, 'DELETE')
631+
},
632+
futuresCancelAllOpenOrders: payload => {
633+
const isConditional = payload?.conditional
634+
let payloadCopy = payload
635+
if (payload && 'conditional' in payload) {
636+
payloadCopy = { ...payload }
637+
delete payloadCopy.conditional
638+
}
639+
640+
if (isConditional) {
641+
return privCall('/fapi/v1/algoOpenOrders', payloadCopy, 'DELETE')
642+
}
643+
return privCall('/fapi/v1/allOpenOrders', payloadCopy, 'DELETE')
644+
},
579645
futuresCancelBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'DELETE'),
580-
futuresOpenOrders: payload => privCall('/fapi/v1/openOrders', payload),
581-
futuresAllOrders: payload => privCall('/fapi/v1/allOrders', payload),
646+
futuresOpenOrders: payload => {
647+
const isConditional = payload?.conditional
648+
let payloadCopy = payload
649+
if (payload && 'conditional' in payload) {
650+
payloadCopy = { ...payload }
651+
delete payloadCopy.conditional
652+
}
653+
654+
if (isConditional) {
655+
return privCall('/fapi/v1/openAlgoOrders', payloadCopy)
656+
}
657+
return privCall('/fapi/v1/openOrders', payloadCopy)
658+
},
659+
futuresAllOrders: payload => {
660+
const isConditional = payload?.conditional
661+
let payloadCopy = payload
662+
if (payload && 'conditional' in payload) {
663+
payloadCopy = { ...payload }
664+
delete payloadCopy.conditional
665+
}
666+
667+
if (isConditional) {
668+
return privCall('/fapi/v1/allAlgoOrders', payloadCopy)
669+
}
670+
return privCall('/fapi/v1/allOrders', payloadCopy)
671+
},
582672
futuresPositionRisk: payload => privCall('/fapi/v2/positionRisk', payload),
583673
futuresLeverageBracket: payload => privCall('/fapi/v1/leverageBracket', payload),
584674
futuresAccountBalance: payload => privCall('/fapi/v2/balance', payload),
@@ -595,6 +685,23 @@ export default opts => {
595685
getMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload),
596686
setMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload, 'POST'),
597687

688+
// Algo Orders (Conditional Orders)
689+
futuresCreateAlgoOrder: payload => {
690+
if (!payload.clientAlgoId) {
691+
payload.clientAlgoId = futuresP()
692+
}
693+
if (!payload.algoType) {
694+
payload.algoType = 'CONDITIONAL'
695+
}
696+
return privCall('/fapi/v1/algoOrder', payload, 'POST')
697+
},
698+
futuresCancelAlgoOrder: payload => privCall('/fapi/v1/algoOrder', payload, 'DELETE'),
699+
futuresCancelAllAlgoOpenOrders: payload =>
700+
privCall('/fapi/v1/algoOpenOrders', payload, 'DELETE'),
701+
futuresGetAlgoOrder: payload => privCall('/fapi/v1/algoOrder', payload),
702+
futuresGetOpenAlgoOrders: payload => privCall('/fapi/v1/openAlgoOrders', payload),
703+
futuresGetAllAlgoOrders: payload => privCall('/fapi/v1/allAlgoOrders', payload),
704+
598705
// Delivery endpoints
599706
deliveryPing: () => pubCall('/dapi/v1/ping').then(() => true),
600707
deliveryTime: () => pubCall('/dapi/v1/time').then(r => r.serverTime),

0 commit comments

Comments
 (0)