Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"build": "rm -rf dist && babel src -d dist",
"prepare": "npm run build",
"test": "npm run test:ava && npm run test:browser",
"test:ava": "ava --timeout=10s -v",
"test:ava": "ava --timeout=90s -v",
"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",
"test:browser:signature": "node test/browser/browser-test-runner.mjs",
"test:browser:websocket": "ava test/browser/websocket-browser.test.js --timeout=15s -v",
Expand Down
121 changes: 114 additions & 7 deletions src/http-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,15 +570,105 @@ export default opts => {
futuresFundingRate: payload =>
checkParams('fundingRate', payload, ['symbol']) &&
pubCall('/fapi/v1/fundingRate', payload),
futuresOrder: payload => order(privCall, payload, '/fapi/v1/order'),
futuresOrder: payload => {
// Check if this is a conditional order type that should be routed to algo endpoint
const orderType = payload?.type?.toUpperCase()
const conditionalTypes = [
'STOP',
'STOP_MARKET',
'TAKE_PROFIT',
'TAKE_PROFIT_MARKET',
'TRAILING_STOP_MARKET',
]

if (orderType && conditionalTypes.includes(orderType)) {
// Route to algo order endpoint
const algoPayload = { ...payload }
if (!algoPayload.clientAlgoId) {
algoPayload.clientAlgoId = futuresP()
}
delete algoPayload.newClientOrderId
algoPayload.algoType = 'CONDITIONAL'
if (algoPayload.stopPrice && !algoPayload.triggerPrice) {
algoPayload.triggerPrice = algoPayload.stopPrice
delete algoPayload.stopPrice
}
return privCall('/fapi/v1/algoOrder', algoPayload, 'POST')
}
// Use regular order endpoint
return order(privCall, payload, '/fapi/v1/order')
},
futuresBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'POST'),
futuresGetOrder: payload => privCall('/fapi/v1/order', payload),
futuresCancelOrder: payload => privCall('/fapi/v1/order', payload, 'DELETE'),
futuresCancelAllOpenOrders: payload =>
privCall('/fapi/v1/allOpenOrders', payload, 'DELETE'),
futuresGetOrder: payload => {
// Check if this is a request for a conditional/algo order
const isConditional = payload?.conditional
const hasAlgoId = payload?.algoId || payload?.clientAlgoId
let payloadCopy = payload
if (payload && 'conditional' in payload) {
payloadCopy = { ...payload }
delete payloadCopy.conditional
}

if (isConditional || hasAlgoId) {
return privCall('/fapi/v1/algoOrder', payloadCopy)
}
return privCall('/fapi/v1/order', payloadCopy)
},
futuresCancelOrder: payload => {
// Check if this is a request for a conditional/algo order
const isConditional = payload?.conditional
const hasAlgoId = payload?.algoId || payload?.clientAlgoId
let payloadCopy = payload
if (payload && 'conditional' in payload) {
payloadCopy = { ...payload }
delete payloadCopy.conditional
}

if (isConditional || hasAlgoId) {
return privCall('/fapi/v1/algoOrder', payloadCopy, 'DELETE')
}
return privCall('/fapi/v1/order', payloadCopy, 'DELETE')
},
futuresCancelAllOpenOrders: payload => {
const isConditional = payload?.conditional
let payloadCopy = payload
if (payload && 'conditional' in payload) {
payloadCopy = { ...payload }
delete payloadCopy.conditional
}

if (isConditional) {
return privCall('/fapi/v1/algoOpenOrders', payloadCopy, 'DELETE')
}
return privCall('/fapi/v1/allOpenOrders', payloadCopy, 'DELETE')
},
futuresCancelBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'DELETE'),
futuresOpenOrders: payload => privCall('/fapi/v1/openOrders', payload),
futuresAllOrders: payload => privCall('/fapi/v1/allOrders', payload),
futuresOpenOrders: payload => {
const isConditional = payload?.conditional
let payloadCopy = payload
if (payload && 'conditional' in payload) {
payloadCopy = { ...payload }
delete payloadCopy.conditional
}

if (isConditional) {
return privCall('/fapi/v1/openAlgoOrders', payloadCopy)
}
return privCall('/fapi/v1/openOrders', payloadCopy)
},
futuresAllOrders: payload => {
const isConditional = payload?.conditional
let payloadCopy = payload
if (payload && 'conditional' in payload) {
payloadCopy = { ...payload }
delete payloadCopy.conditional
}

if (isConditional) {
return privCall('/fapi/v1/allAlgoOrders', payloadCopy)
}
return privCall('/fapi/v1/allOrders', payloadCopy)
},
futuresPositionRisk: payload => privCall('/fapi/v2/positionRisk', payload),
futuresLeverageBracket: payload => privCall('/fapi/v1/leverageBracket', payload),
futuresAccountBalance: payload => privCall('/fapi/v2/balance', payload),
Expand All @@ -595,6 +685,23 @@ export default opts => {
getMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload),
setMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload, 'POST'),

// Algo Orders (Conditional Orders)
futuresCreateAlgoOrder: payload => {
if (!payload.clientAlgoId) {
payload.clientAlgoId = futuresP()
}
if (!payload.algoType) {
payload.algoType = 'CONDITIONAL'
}
return privCall('/fapi/v1/algoOrder', payload, 'POST')
},
futuresCancelAlgoOrder: payload => privCall('/fapi/v1/algoOrder', payload, 'DELETE'),
futuresCancelAllAlgoOpenOrders: payload =>
privCall('/fapi/v1/algoOpenOrders', payload, 'DELETE'),
futuresGetAlgoOrder: payload => privCall('/fapi/v1/algoOrder', payload),
futuresGetOpenAlgoOrders: payload => privCall('/fapi/v1/openAlgoOrders', payload),
futuresGetAllAlgoOrders: payload => privCall('/fapi/v1/allAlgoOrders', payload),

// Delivery endpoints
deliveryPing: () => pubCall('/dapi/v1/ping').then(() => true),
deliveryTime: () => pubCall('/dapi/v1/time').then(r => r.serverTime),
Expand Down
Loading