@orderly.network/hooks 2.8.0 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -10
- package/dist/index.d.ts +3 -10
- package/dist/index.js +2052 -2088
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2052 -2089
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
package/dist/index.mjs
CHANGED
|
@@ -36,9 +36,9 @@ var __export = (target, all) => {
|
|
|
36
36
|
// src/version.ts
|
|
37
37
|
if (typeof window !== "undefined") {
|
|
38
38
|
window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
|
|
39
|
-
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.8.
|
|
39
|
+
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.8.1";
|
|
40
40
|
}
|
|
41
|
-
var version_default = "2.8.
|
|
41
|
+
var version_default = "2.8.1";
|
|
42
42
|
var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
|
|
43
43
|
var noCacheConfig = {
|
|
44
44
|
dedupingInterval: 0,
|
|
@@ -1224,7 +1224,7 @@ function checkTPSLOrderTypeIsMarket(key, values) {
|
|
|
1224
1224
|
}
|
|
1225
1225
|
function tpslCalculateHelper(key, inputs, options = {}) {
|
|
1226
1226
|
const { symbol } = options;
|
|
1227
|
-
if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage" && key !== "tp_order_price" && key !== "sl_order_price" && key !== "tp_order_type" && key !== "sl_order_type"
|
|
1227
|
+
if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage" && key !== "tp_order_price" && key !== "sl_order_price" && key !== "tp_order_type" && key !== "sl_order_type") {
|
|
1228
1228
|
return {
|
|
1229
1229
|
[key]: inputs.value
|
|
1230
1230
|
};
|
|
@@ -1263,19 +1263,6 @@ function tpslCalculateHelper(key, inputs, options = {}) {
|
|
|
1263
1263
|
}
|
|
1264
1264
|
break;
|
|
1265
1265
|
}
|
|
1266
|
-
case "tp_enable":
|
|
1267
|
-
case "sl_enable": {
|
|
1268
|
-
return {
|
|
1269
|
-
[`${keyPrefix}enable`]: inputs.value,
|
|
1270
|
-
[`${keyPrefix}order_type`]: OrderType.MARKET,
|
|
1271
|
-
[`${keyPrefix}trigger_price`]: "",
|
|
1272
|
-
[`${keyPrefix}order_price`]: "",
|
|
1273
|
-
[`${keyPrefix}offset`]: "",
|
|
1274
|
-
[`${keyPrefix}offset_percentage`]: "",
|
|
1275
|
-
[`${keyPrefix}pnl`]: "",
|
|
1276
|
-
[`${keyPrefix}ROI`]: ""
|
|
1277
|
-
};
|
|
1278
|
-
}
|
|
1279
1266
|
case "tp_pnl":
|
|
1280
1267
|
case "sl_pnl": {
|
|
1281
1268
|
pnl = inputs.value;
|
|
@@ -1624,7 +1611,6 @@ var getCalculateHandler = (fieldName) => {
|
|
|
1624
1611
|
case "total": {
|
|
1625
1612
|
return totalInputHandle;
|
|
1626
1613
|
}
|
|
1627
|
-
case "tp_enable":
|
|
1628
1614
|
case "tp_pnl":
|
|
1629
1615
|
case "sl_pnl":
|
|
1630
1616
|
case "tp_trigger_price":
|
|
@@ -1635,7 +1621,6 @@ var getCalculateHandler = (fieldName) => {
|
|
|
1635
1621
|
case "sl_offset_percentage":
|
|
1636
1622
|
case "tp_order_price":
|
|
1637
1623
|
case "tp_order_type":
|
|
1638
|
-
case "sl_enable":
|
|
1639
1624
|
case "sl_order_type":
|
|
1640
1625
|
case "sl_order_price":
|
|
1641
1626
|
return tpslInputHandle;
|
|
@@ -2735,6 +2720,7 @@ var useAppStore = create()(
|
|
|
2735
2720
|
);
|
|
2736
2721
|
var useAccountInfo2 = () => useAppStore((state) => state.accountInfo);
|
|
2737
2722
|
var usePortfolio = () => useAppStore((state) => state.portfolio);
|
|
2723
|
+
var useFundingRateBySymbol = (symbol) => useAppStore((state) => state.fundingRates?.[symbol]);
|
|
2738
2724
|
|
|
2739
2725
|
// src/orderly/useRwaSymbolsInfo.ts
|
|
2740
2726
|
var isCurrentlyTrading = (nextClose, status, currentTime = Date.now()) => {
|
|
@@ -2756,10 +2742,16 @@ var computeSymbolState = (rwaSymbol, currentTime) => {
|
|
|
2756
2742
|
let closeTimeInterval;
|
|
2757
2743
|
let openTimeInterval;
|
|
2758
2744
|
if (next_close && typeof next_close === "number" && next_close > currentTime) {
|
|
2759
|
-
closeTimeInterval = Math.max(
|
|
2745
|
+
closeTimeInterval = Math.max(
|
|
2746
|
+
0,
|
|
2747
|
+
Math.floor((next_close - currentTime) / 1e3)
|
|
2748
|
+
);
|
|
2760
2749
|
}
|
|
2761
2750
|
if (next_open && typeof next_open === "number" && next_open > currentTime) {
|
|
2762
|
-
openTimeInterval = Math.max(
|
|
2751
|
+
openTimeInterval = Math.max(
|
|
2752
|
+
0,
|
|
2753
|
+
Math.floor((next_open - currentTime) / 1e3)
|
|
2754
|
+
);
|
|
2763
2755
|
}
|
|
2764
2756
|
return {
|
|
2765
2757
|
isRwa: true,
|
|
@@ -2770,46 +2762,48 @@ var computeSymbolState = (rwaSymbol, currentTime) => {
|
|
|
2770
2762
|
openTimeInterval
|
|
2771
2763
|
};
|
|
2772
2764
|
};
|
|
2773
|
-
var useRwaSymbolsRuntimeStore = create(
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
const
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2765
|
+
var useRwaSymbolsRuntimeStore = create(
|
|
2766
|
+
(set, get3) => ({
|
|
2767
|
+
computedStates: {},
|
|
2768
|
+
currentTime: Date.now(),
|
|
2769
|
+
timerId: void 0,
|
|
2770
|
+
startTimer: () => {
|
|
2771
|
+
const state = get3();
|
|
2772
|
+
if (state.timerId) {
|
|
2773
|
+
clearInterval(state.timerId);
|
|
2774
|
+
}
|
|
2775
|
+
const timerId = setInterval(() => {
|
|
2776
|
+
const currentTime = Date.now();
|
|
2777
|
+
const rwaSymbolsInfo = useAppStore.getState().rwaSymbolsInfo;
|
|
2778
|
+
if (!rwaSymbolsInfo) {
|
|
2779
|
+
set({ currentTime });
|
|
2780
|
+
return;
|
|
2781
|
+
}
|
|
2782
|
+
const computedStates = {};
|
|
2783
|
+
Object.entries(rwaSymbolsInfo).forEach(([symbol, rwaSymbol]) => {
|
|
2784
|
+
computedStates[symbol] = computeSymbolState(rwaSymbol, currentTime);
|
|
2785
|
+
});
|
|
2786
|
+
set({ computedStates, currentTime });
|
|
2787
|
+
}, 1e3);
|
|
2788
|
+
set({ timerId });
|
|
2789
|
+
},
|
|
2790
|
+
stopTimer: () => {
|
|
2791
|
+
const state = get3();
|
|
2792
|
+
if (state.timerId) {
|
|
2793
|
+
clearInterval(state.timerId);
|
|
2794
|
+
set({ timerId: void 0 });
|
|
2788
2795
|
}
|
|
2796
|
+
},
|
|
2797
|
+
updateComputedStates: (rwaSymbolsInfo) => {
|
|
2798
|
+
const currentTime = get3().currentTime;
|
|
2789
2799
|
const computedStates = {};
|
|
2790
2800
|
Object.entries(rwaSymbolsInfo).forEach(([symbol, rwaSymbol]) => {
|
|
2791
2801
|
computedStates[symbol] = computeSymbolState(rwaSymbol, currentTime);
|
|
2792
2802
|
});
|
|
2793
|
-
set({ computedStates
|
|
2794
|
-
}, 1e3);
|
|
2795
|
-
set({ timerId });
|
|
2796
|
-
},
|
|
2797
|
-
stopTimer: () => {
|
|
2798
|
-
const state = get3();
|
|
2799
|
-
if (state.timerId) {
|
|
2800
|
-
clearInterval(state.timerId);
|
|
2801
|
-
set({ timerId: void 0 });
|
|
2803
|
+
set({ computedStates });
|
|
2802
2804
|
}
|
|
2803
|
-
}
|
|
2804
|
-
|
|
2805
|
-
const currentTime = get3().currentTime;
|
|
2806
|
-
const computedStates = {};
|
|
2807
|
-
Object.entries(rwaSymbolsInfo).forEach(([symbol, rwaSymbol]) => {
|
|
2808
|
-
computedStates[symbol] = computeSymbolState(rwaSymbol, currentTime);
|
|
2809
|
-
});
|
|
2810
|
-
set({ computedStates });
|
|
2811
|
-
}
|
|
2812
|
-
}));
|
|
2805
|
+
})
|
|
2806
|
+
);
|
|
2813
2807
|
var useInitRwaSymbolsRuntime = () => {
|
|
2814
2808
|
const rwaSymbolsInfo = useRwaSymbolsInfoStore();
|
|
2815
2809
|
const { startTimer, stopTimer, updateComputedStates } = useRwaSymbolsRuntimeStore();
|
|
@@ -3285,1914 +3279,1918 @@ var useWSObserver = (calculatorService) => {
|
|
|
3285
3279
|
};
|
|
3286
3280
|
}, []);
|
|
3287
3281
|
};
|
|
3288
|
-
var useApiStatusStore = create()(
|
|
3289
|
-
immer((set) => ({
|
|
3290
|
-
apis: {
|
|
3291
|
-
positions: {
|
|
3292
|
-
loading: false
|
|
3293
|
-
}
|
|
3294
|
-
},
|
|
3295
|
-
actions: {
|
|
3296
|
-
updateStatus: (key, status) => {
|
|
3297
|
-
set((state) => {
|
|
3298
|
-
state.apis[key] = status;
|
|
3299
|
-
});
|
|
3300
|
-
},
|
|
3301
|
-
updateApiLoading: (key, loading) => {
|
|
3302
|
-
set((state) => {
|
|
3303
|
-
state.apis[key].loading = loading;
|
|
3304
|
-
});
|
|
3305
|
-
},
|
|
3306
|
-
updateApiError: (key, error) => {
|
|
3307
|
-
set((state) => {
|
|
3308
|
-
state.apis[key] = {
|
|
3309
|
-
loading: false,
|
|
3310
|
-
error
|
|
3311
|
-
};
|
|
3312
|
-
});
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
}))
|
|
3316
|
-
);
|
|
3317
|
-
var useApiStatusActions = () => useApiStatusStore((state) => state.actions);
|
|
3318
|
-
var useTokensInfoStore = create(
|
|
3319
|
-
(set) => ({
|
|
3320
|
-
tokensInfo: [],
|
|
3321
|
-
setTokensInfo(data) {
|
|
3322
|
-
set({ tokensInfo: data });
|
|
3323
|
-
}
|
|
3324
|
-
})
|
|
3325
|
-
);
|
|
3326
|
-
var useTokensInfo = () => {
|
|
3327
|
-
const tokensInfo = useTokensInfoStore((state) => state.tokensInfo);
|
|
3328
|
-
return tokensInfo;
|
|
3329
|
-
};
|
|
3330
|
-
var useTokenInfo = (token) => {
|
|
3331
|
-
const tokensInfo = useTokensInfo();
|
|
3332
|
-
return useMemo(() => {
|
|
3333
|
-
return tokensInfo?.find((item) => item.token === token);
|
|
3334
|
-
}, [tokensInfo, token]);
|
|
3335
|
-
};
|
|
3336
3282
|
|
|
3337
|
-
// src/orderly/
|
|
3338
|
-
var
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3283
|
+
// src/orderly/orderbook.service.ts
|
|
3284
|
+
var defaultRawOrderBook = {
|
|
3285
|
+
asks: [],
|
|
3286
|
+
bids: [],
|
|
3287
|
+
ts: 0
|
|
3342
3288
|
};
|
|
3343
|
-
var
|
|
3344
|
-
markPrices: {},
|
|
3345
|
-
// orderBook: {},
|
|
3346
|
-
// ask_bid: [],
|
|
3347
|
-
actions: {
|
|
3348
|
-
updateMarkPrice: (markPrice) => {
|
|
3349
|
-
set({
|
|
3350
|
-
markPrices: markPrice
|
|
3351
|
-
});
|
|
3352
|
-
},
|
|
3353
|
-
getMarkPriceBySymbol: (symbol) => {
|
|
3354
|
-
return get3().markPrices[symbol];
|
|
3355
|
-
}
|
|
3356
|
-
}
|
|
3357
|
-
}));
|
|
3358
|
-
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
3359
|
-
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
3360
|
-
|
|
3361
|
-
// src/orderly/calculator/markPrice.ts
|
|
3362
|
-
var MarketCalculatorName = "markPriceCalculator";
|
|
3363
|
-
var MarkPriceCalculator = class extends BaseCalculator {
|
|
3289
|
+
var OrderbookService = class _OrderbookService {
|
|
3364
3290
|
constructor() {
|
|
3365
|
-
|
|
3366
|
-
this.
|
|
3367
|
-
}
|
|
3368
|
-
calc(scope, data, ctx) {
|
|
3369
|
-
return data;
|
|
3291
|
+
this.bufferedOrderBookUpdates = {};
|
|
3292
|
+
this.rawOrderBook = {};
|
|
3370
3293
|
}
|
|
3371
|
-
|
|
3372
|
-
|
|
3294
|
+
static getInstance() {
|
|
3295
|
+
if (!this.instance) {
|
|
3296
|
+
this.instance = new _OrderbookService();
|
|
3297
|
+
}
|
|
3298
|
+
return this.instance;
|
|
3373
3299
|
}
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
// src/orderly/calculator/calculatorContext.ts
|
|
3377
|
-
var CalculatorContext = class _CalculatorContext {
|
|
3378
|
-
static get instance() {
|
|
3379
|
-
return this._instance;
|
|
3300
|
+
sortBufferedOrderBookUpdates(symbol) {
|
|
3301
|
+
this.bufferedOrderBookUpdates[symbol]?.sort((a, b) => a.ts - b.ts);
|
|
3380
3302
|
}
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3303
|
+
applyUpdateToRawOrderBook(symbol, update) {
|
|
3304
|
+
const rawOrderBook = this.rawOrderBook[symbol];
|
|
3305
|
+
if (!rawOrderBook || rawOrderBook.ts > update.prevTs) {
|
|
3306
|
+
return;
|
|
3384
3307
|
}
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3308
|
+
const askMap = /* @__PURE__ */ new Map();
|
|
3309
|
+
const bidMap = /* @__PURE__ */ new Map();
|
|
3310
|
+
rawOrderBook.asks.forEach((ask) => {
|
|
3311
|
+
askMap.set(ask[0], ask[1]);
|
|
3312
|
+
});
|
|
3313
|
+
rawOrderBook.bids.forEach((bid) => {
|
|
3314
|
+
bidMap.set(bid[0], bid[1]);
|
|
3315
|
+
});
|
|
3316
|
+
update.asks.forEach(
|
|
3317
|
+
(ask) => ask[1] === 0 ? askMap.delete(ask[0]) : askMap.set(ask[0], ask[1])
|
|
3318
|
+
);
|
|
3319
|
+
update.bids.forEach(
|
|
3320
|
+
(bid) => bid[1] === 0 ? bidMap.delete(bid[0]) : bidMap.set(bid[0], bid[1])
|
|
3321
|
+
);
|
|
3322
|
+
rawOrderBook.asks = Array.from(askMap.entries()).sort(
|
|
3323
|
+
(a, b) => a[0] - b[0]
|
|
3324
|
+
);
|
|
3325
|
+
rawOrderBook.bids = Array.from(bidMap.entries()).sort(
|
|
3326
|
+
(a, b) => b[0] - a[0]
|
|
3327
|
+
);
|
|
3328
|
+
rawOrderBook.ts = update.ts;
|
|
3392
3329
|
}
|
|
3393
|
-
|
|
3394
|
-
this.
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
return this;
|
|
3330
|
+
applyBufferedUpdatesToRawOrderBooks(symbol) {
|
|
3331
|
+
this.bufferedOrderBookUpdates[symbol]?.forEach((update) => {
|
|
3332
|
+
this.applyUpdateToRawOrderBook(symbol, update);
|
|
3333
|
+
});
|
|
3398
3334
|
}
|
|
3399
|
-
|
|
3400
|
-
this.
|
|
3401
|
-
this.symbolsInfo = useAppStore.getState().symbolsInfo;
|
|
3402
|
-
this.fundingRates = useAppStore.getState().fundingRates;
|
|
3403
|
-
this.tokensInfo = useTokensInfoStore.getState().tokensInfo;
|
|
3335
|
+
deleteBufferedOrderBookUpdates(symbol) {
|
|
3336
|
+
delete this.bufferedOrderBookUpdates[symbol];
|
|
3404
3337
|
}
|
|
3405
|
-
|
|
3406
|
-
|
|
3338
|
+
commitOrderBook(symbol) {
|
|
3339
|
+
const rawOrderBook = this.rawOrderBook[symbol];
|
|
3340
|
+
if (!rawOrderBook) {
|
|
3341
|
+
return;
|
|
3342
|
+
}
|
|
3407
3343
|
}
|
|
3408
|
-
|
|
3409
|
-
|
|
3344
|
+
pushUpdateToBuffer(symbol, update) {
|
|
3345
|
+
if (this.bufferedOrderBookUpdates[symbol] === void 0) {
|
|
3346
|
+
this.bufferedOrderBookUpdates[symbol] = [];
|
|
3347
|
+
}
|
|
3348
|
+
const buffer = this.bufferedOrderBookUpdates[symbol];
|
|
3349
|
+
if (buffer.length > 0) {
|
|
3350
|
+
const lastUpdate = buffer[buffer.length - 1];
|
|
3351
|
+
if (lastUpdate.ts !== update.prevTs) {
|
|
3352
|
+
this.bufferedOrderBookUpdates[symbol] = [];
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
this.bufferedOrderBookUpdates[symbol].push(update);
|
|
3410
3356
|
}
|
|
3411
|
-
|
|
3412
|
-
this.
|
|
3413
|
-
|
|
3414
|
-
|
|
3357
|
+
isValidFullOrderBook(symbol, currentTs) {
|
|
3358
|
+
if ((this.bufferedOrderBookUpdates[symbol]?.length ?? 0) !== 0) {
|
|
3359
|
+
const earliestUpdates = this.bufferedOrderBookUpdates[symbol][0];
|
|
3360
|
+
return earliestUpdates.prevTs <= currentTs;
|
|
3361
|
+
}
|
|
3362
|
+
return true;
|
|
3415
3363
|
}
|
|
3416
|
-
|
|
3417
|
-
|
|
3364
|
+
setFullOrderbook(symbol, rawOrderbook) {
|
|
3365
|
+
const { ts } = rawOrderbook;
|
|
3366
|
+
this.rawOrderBook[symbol] = rawOrderbook;
|
|
3367
|
+
this.sortBufferedOrderBookUpdates(symbol);
|
|
3368
|
+
if (this.isValidFullOrderBook(symbol, ts)) {
|
|
3369
|
+
this.applyBufferedUpdatesToRawOrderBooks(symbol);
|
|
3370
|
+
}
|
|
3418
3371
|
}
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3372
|
+
updateOrderbook(symbol, update, callback) {
|
|
3373
|
+
const { asks, bids, prevTs, ts } = update;
|
|
3374
|
+
const rawOrderBook = this.rawOrderBook[symbol];
|
|
3375
|
+
if (!rawOrderBook) {
|
|
3376
|
+
return;
|
|
3377
|
+
}
|
|
3378
|
+
const currentTs = rawOrderBook.ts;
|
|
3379
|
+
if (currentTs === 0) {
|
|
3380
|
+
this.pushUpdateToBuffer(symbol, { asks, bids, prevTs, ts });
|
|
3381
|
+
return;
|
|
3382
|
+
}
|
|
3383
|
+
if (prevTs !== currentTs) {
|
|
3384
|
+
this.pushUpdateToBuffer(symbol, { asks, bids, prevTs, ts });
|
|
3385
|
+
if (callback) {
|
|
3386
|
+
callback();
|
|
3387
|
+
}
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
this.applyUpdateToRawOrderBook(symbol, update);
|
|
3391
|
+
this.deleteBufferedOrderBookUpdates(symbol);
|
|
3425
3392
|
}
|
|
3426
|
-
|
|
3427
|
-
this.
|
|
3393
|
+
getRawOrderbook(symbol) {
|
|
3394
|
+
return this.rawOrderBook[symbol];
|
|
3428
3395
|
}
|
|
3429
|
-
|
|
3430
|
-
|
|
3396
|
+
resetOrderBook(symbol) {
|
|
3397
|
+
this.rawOrderBook[symbol] = defaultRawOrderBook;
|
|
3431
3398
|
}
|
|
3432
3399
|
};
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
var
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3400
|
+
var orderBookService = OrderbookService.getInstance();
|
|
3401
|
+
var orderbook_service_default = orderBookService;
|
|
3402
|
+
var useMarkPrice = (symbol) => {
|
|
3403
|
+
const ws = useWS();
|
|
3404
|
+
const [price, setPrice] = useState(0);
|
|
3405
|
+
useEffect(() => {
|
|
3406
|
+
const unsubscribe = ws.subscribe(`${symbol}@markprice`, {
|
|
3407
|
+
onMessage: (message) => {
|
|
3408
|
+
setPrice(message.price);
|
|
3409
|
+
}
|
|
3410
|
+
});
|
|
3411
|
+
return () => {
|
|
3412
|
+
unsubscribe?.();
|
|
3413
|
+
};
|
|
3414
|
+
}, [symbol]);
|
|
3415
|
+
return { data: price };
|
|
3416
|
+
};
|
|
3417
|
+
var useIndexPrice = (symbol) => {
|
|
3418
|
+
symbol = symbol.replace("PERP", "SPOT");
|
|
3419
|
+
const ws = useWS();
|
|
3420
|
+
return useSWRSubscription(`${symbol}@indexprice`, (key, { next }) => {
|
|
3421
|
+
const unsubscribe = ws.subscribe(`${symbol}@indexprice`, {
|
|
3422
|
+
onMessage: (message) => {
|
|
3423
|
+
next(null, message.price);
|
|
3424
|
+
}
|
|
3425
|
+
});
|
|
3426
|
+
return () => {
|
|
3427
|
+
unsubscribe?.();
|
|
3428
|
+
};
|
|
3429
|
+
});
|
|
3430
|
+
};
|
|
3431
|
+
var useOpenInterest = (symbol) => {
|
|
3432
|
+
const ws = useWS();
|
|
3433
|
+
return useSWRSubscription(`${symbol}@openinterest`, (key, { next }) => {
|
|
3434
|
+
const unsubscribe = ws.subscribe(`${symbol}@openinterest`, {
|
|
3435
|
+
onMessage: (message) => {
|
|
3436
|
+
next(null, message.openInterest);
|
|
3437
|
+
}
|
|
3438
|
+
});
|
|
3439
|
+
return () => {
|
|
3440
|
+
unsubscribe?.();
|
|
3441
|
+
};
|
|
3442
|
+
});
|
|
3443
|
+
};
|
|
3444
|
+
var useFutures = () => {
|
|
3445
|
+
const { data, isLoading, error } = useQuery(
|
|
3446
|
+
`/v1/public/futures`,
|
|
3447
|
+
{
|
|
3448
|
+
revalidateOnFocus: false
|
|
3453
3449
|
}
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3450
|
+
);
|
|
3451
|
+
const [sortedData, setSortedData] = useState(data);
|
|
3452
|
+
useWS();
|
|
3453
|
+
useEffect(() => {
|
|
3454
|
+
}, []);
|
|
3455
|
+
useEffect(() => {
|
|
3456
|
+
if (data) {
|
|
3457
|
+
const sortedData2 = data.sort((a, b) => {
|
|
3458
|
+
return 0;
|
|
3459
|
+
});
|
|
3460
|
+
setSortedData(sortedData2);
|
|
3459
3461
|
}
|
|
3460
|
-
|
|
3462
|
+
}, [data]);
|
|
3463
|
+
const sortBy = useCallback((key) => {
|
|
3464
|
+
}, [data]);
|
|
3465
|
+
const filterBy = useCallback((key) => {
|
|
3466
|
+
}, [data]);
|
|
3467
|
+
return {
|
|
3468
|
+
data: sortedData,
|
|
3469
|
+
sortBy,
|
|
3470
|
+
filterBy,
|
|
3471
|
+
isLoading,
|
|
3472
|
+
error
|
|
3473
|
+
};
|
|
3474
|
+
};
|
|
3475
|
+
|
|
3476
|
+
// src/orderly/useTickerStream.ts
|
|
3477
|
+
var useTickerStream = (symbol) => {
|
|
3478
|
+
if (!symbol) {
|
|
3479
|
+
throw new SDKError("Symbol is required");
|
|
3461
3480
|
}
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
this.referenceCount.set(ref_count_name, count - 1);
|
|
3467
|
-
return;
|
|
3481
|
+
const { data: info } = useQuery(
|
|
3482
|
+
`/v1/public/futures/${symbol}`,
|
|
3483
|
+
{
|
|
3484
|
+
revalidateOnFocus: false
|
|
3468
3485
|
}
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3486
|
+
);
|
|
3487
|
+
const [ticker, setTicker] = useState();
|
|
3488
|
+
const ws = useWS();
|
|
3489
|
+
useEffect(() => {
|
|
3490
|
+
const unsubscribe = ws.subscribe(
|
|
3491
|
+
// { event: "subscribe", topic: "markprices" },
|
|
3492
|
+
`${symbol}@ticker`,
|
|
3493
|
+
{
|
|
3494
|
+
onMessage: (message) => {
|
|
3495
|
+
if (message.symbol !== symbol)
|
|
3496
|
+
return;
|
|
3497
|
+
setTicker(message);
|
|
3498
|
+
}
|
|
3499
|
+
// onUnsubscribe: () => {
|
|
3500
|
+
// return "markprices";
|
|
3501
|
+
// },
|
|
3502
|
+
// onError: (error: any) => {
|
|
3503
|
+
//
|
|
3504
|
+
// },
|
|
3475
3505
|
}
|
|
3506
|
+
);
|
|
3507
|
+
return () => {
|
|
3508
|
+
setTicker(void 0);
|
|
3509
|
+
unsubscribe?.();
|
|
3510
|
+
};
|
|
3511
|
+
}, [symbol]);
|
|
3512
|
+
const { data: markPrice } = useMarkPrice(symbol);
|
|
3513
|
+
const { data: indexPrice } = useIndexPrice(symbol);
|
|
3514
|
+
const { data: openInterest } = useOpenInterest(symbol);
|
|
3515
|
+
const { data: futures } = useFutures();
|
|
3516
|
+
const value = useMemo(() => {
|
|
3517
|
+
if (!info)
|
|
3518
|
+
return null;
|
|
3519
|
+
if (!ticker || ticker.symbol !== symbol)
|
|
3520
|
+
return info;
|
|
3521
|
+
const futureIndex = futures?.findIndex(
|
|
3522
|
+
(item) => item.symbol === symbol
|
|
3523
|
+
);
|
|
3524
|
+
let _oi = openInterest;
|
|
3525
|
+
if (!_oi && futureIndex !== -1 && futures) {
|
|
3526
|
+
_oi = futures[futureIndex].open_interest;
|
|
3476
3527
|
}
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3528
|
+
const config = {
|
|
3529
|
+
...info,
|
|
3530
|
+
mark_price: markPrice,
|
|
3531
|
+
index_price: indexPrice,
|
|
3532
|
+
open_interest: _oi
|
|
3533
|
+
};
|
|
3534
|
+
if (ticker.open !== void 0) {
|
|
3535
|
+
config["24h_open"] = ticker.open;
|
|
3482
3536
|
}
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
return;
|
|
3537
|
+
if (ticker.close !== void 0) {
|
|
3538
|
+
config["24h_close"] = ticker.close;
|
|
3486
3539
|
}
|
|
3487
|
-
if (
|
|
3488
|
-
|
|
3489
|
-
this.calcQueue.push({ scope, data, options });
|
|
3490
|
-
await this.handleCalcQueue(ctx);
|
|
3491
|
-
this.ctx = ctx;
|
|
3492
|
-
}
|
|
3493
|
-
// private async handlePendingCalc() {
|
|
3494
|
-
// // console.log("[handlePendingCalc]:", this.pendingCalc);
|
|
3495
|
-
// if (this.pendingCalc.length === 0) return;
|
|
3496
|
-
// this.calcQueue = [...this.pendingCalc, ...this.calcQueue];
|
|
3497
|
-
// this.pendingCalc = [];
|
|
3498
|
-
// }
|
|
3499
|
-
async handleCalcQueue(context) {
|
|
3500
|
-
const first = this.calcQueue.shift();
|
|
3501
|
-
if (first) {
|
|
3502
|
-
const { scope, data, options } = first;
|
|
3503
|
-
const ctx = context || CalculatorContext.create(scope, data);
|
|
3504
|
-
const calculators = this.calculators.get(scope);
|
|
3505
|
-
if (Array.isArray(calculators) && calculators.length) {
|
|
3506
|
-
try {
|
|
3507
|
-
await this.scheduler.calc(scope, calculators, data, ctx);
|
|
3508
|
-
} catch (e) {
|
|
3509
|
-
}
|
|
3510
|
-
if (!options?.skipUpdate) {
|
|
3511
|
-
this.scheduler.update(scope, calculators, ctx.outputToValue());
|
|
3512
|
-
}
|
|
3513
|
-
}
|
|
3514
|
-
if (this.calcQueue.length) {
|
|
3515
|
-
this.handleCalcQueue(ctx);
|
|
3516
|
-
}
|
|
3540
|
+
if (ticker.high !== void 0) {
|
|
3541
|
+
config["24h_high"] = ticker.high;
|
|
3517
3542
|
}
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
this.calcQueue = [];
|
|
3521
|
-
this.ctx?.clearCache();
|
|
3522
|
-
}
|
|
3523
|
-
get windowIsVisible() {
|
|
3524
|
-
if (typeof document === "undefined") {
|
|
3525
|
-
return true;
|
|
3543
|
+
if (ticker.low !== void 0) {
|
|
3544
|
+
config["24h_low"] = ticker.low;
|
|
3526
3545
|
}
|
|
3527
|
-
|
|
3528
|
-
|
|
3546
|
+
if (ticker.volume !== void 0) {
|
|
3547
|
+
config["24h_volumn"] = ticker.volume;
|
|
3548
|
+
config["24h_volume"] = ticker.volume;
|
|
3549
|
+
}
|
|
3550
|
+
if (ticker.close !== void 0 && ticker.open !== void 0) {
|
|
3551
|
+
config["change"] = new Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
|
|
3552
|
+
config["24h_change"] = new Decimal(ticker.close).minus(ticker.open).toNumber();
|
|
3553
|
+
}
|
|
3554
|
+
return config;
|
|
3555
|
+
}, [info, symbol, ticker, futures, openInterest]);
|
|
3556
|
+
return value;
|
|
3529
3557
|
};
|
|
3530
|
-
var CalculatorServiceID = "CalculatorService";
|
|
3531
3558
|
|
|
3532
|
-
// src/orderly/
|
|
3533
|
-
var
|
|
3534
|
-
|
|
3535
|
-
return
|
|
3536
|
-
callback({
|
|
3537
|
-
didTimeout: false,
|
|
3538
|
-
timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime))
|
|
3539
|
-
});
|
|
3540
|
-
}, 1);
|
|
3559
|
+
// src/orderly/useOrderbookStream.ts
|
|
3560
|
+
var paddingFn = (len) => Array(len).fill([Number.NaN, Number.NaN, Number.NaN, Number.NaN]);
|
|
3561
|
+
var isNumber = (val) => {
|
|
3562
|
+
return typeof val === "number" && !Number.isNaN(val);
|
|
3541
3563
|
};
|
|
3542
|
-
var
|
|
3543
|
-
|
|
3564
|
+
var getPriceKey = (rawPrice, depth, isAsks) => {
|
|
3565
|
+
return new Decimal(rawPrice).div(depth).toDecimalPlaces(0, isAsks ? Decimal.ROUND_CEIL : Decimal.ROUND_FLOOR).mul(depth).toNumber();
|
|
3544
3566
|
};
|
|
3545
|
-
var
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
// run(calculators: Calculator[]) {}
|
|
3549
|
-
calc(scope, calculators, data, ctx) {
|
|
3550
|
-
return new Promise((resolve, reject) => {
|
|
3551
|
-
try {
|
|
3552
|
-
this.computation(
|
|
3553
|
-
calculators,
|
|
3554
|
-
(shard) => {
|
|
3555
|
-
const results = [];
|
|
3556
|
-
for (let index = 0; index < shard.length; index++) {
|
|
3557
|
-
const calculator = shard[index];
|
|
3558
|
-
const result = calculator.calc(scope, data, ctx);
|
|
3559
|
-
if (result) {
|
|
3560
|
-
ctx.saveOutput(calculator.name, result);
|
|
3561
|
-
results.push(result);
|
|
3562
|
-
}
|
|
3563
|
-
}
|
|
3564
|
-
return results;
|
|
3565
|
-
},
|
|
3566
|
-
(results) => {
|
|
3567
|
-
resolve(results);
|
|
3568
|
-
}
|
|
3569
|
-
);
|
|
3570
|
-
} catch (error) {
|
|
3571
|
-
reject(error);
|
|
3572
|
-
}
|
|
3573
|
-
});
|
|
3567
|
+
var reduceItems = (depth, data, isAsks) => {
|
|
3568
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
3569
|
+
return [];
|
|
3574
3570
|
}
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3571
|
+
let newData = [...data];
|
|
3572
|
+
const result = [];
|
|
3573
|
+
if (typeof depth !== "undefined") {
|
|
3574
|
+
const pricesMap = /* @__PURE__ */ new Map();
|
|
3575
|
+
const len = data.length;
|
|
3576
|
+
for (let i = 0; i < len; i++) {
|
|
3577
|
+
const [rawPrice, quantity] = data[i];
|
|
3578
|
+
if (!isNumber(rawPrice) || !isNumber(quantity)) {
|
|
3579
|
+
continue;
|
|
3580
|
+
}
|
|
3581
|
+
const priceKey = getPriceKey(rawPrice, depth, isAsks);
|
|
3582
|
+
const amtByRaw = new Decimal(rawPrice).mul(quantity).toNumber();
|
|
3583
|
+
if (pricesMap.has(priceKey)) {
|
|
3584
|
+
const item = pricesMap.get(priceKey);
|
|
3585
|
+
const sumQty = new Decimal(item[1]).add(quantity).toNumber();
|
|
3586
|
+
const sumAmtByRaw = new Decimal(item[2] ?? 0).add(amtByRaw).toNumber();
|
|
3587
|
+
pricesMap.set(priceKey, [priceKey, sumQty, sumAmtByRaw]);
|
|
3588
|
+
} else {
|
|
3589
|
+
pricesMap.set(priceKey, [priceKey, quantity, amtByRaw]);
|
|
3581
3590
|
}
|
|
3582
3591
|
}
|
|
3583
|
-
|
|
3592
|
+
newData = Array.from(pricesMap.values());
|
|
3584
3593
|
}
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3594
|
+
for (let i = 0; i < newData.length; i++) {
|
|
3595
|
+
const [price, quantity, sumAmtByRaw] = newData[i];
|
|
3596
|
+
if (!isNumber(price) || !isNumber(quantity)) {
|
|
3597
|
+
continue;
|
|
3598
|
+
}
|
|
3599
|
+
const resLen = result.length;
|
|
3600
|
+
const newQuantity = new Decimal(quantity).add(resLen ? result[resLen - 1][2] : 0).toNumber();
|
|
3601
|
+
const pieceAmount = isNumber(sumAmtByRaw) ? sumAmtByRaw : new Decimal(quantity).mul(price).toNumber();
|
|
3602
|
+
const newAmount = new Decimal(pieceAmount).add(resLen ? result[resLen - 1][3] : 0).toNumber();
|
|
3603
|
+
result.push([price, quantity, newQuantity, newAmount]);
|
|
3604
|
+
}
|
|
3605
|
+
return result;
|
|
3606
|
+
};
|
|
3607
|
+
var reduceOrderbook = (depth, level, padding, data) => {
|
|
3608
|
+
let asks = reduceItems(depth, data.asks, true);
|
|
3609
|
+
let bids = reduceItems(depth, data.bids, false);
|
|
3610
|
+
if (asks.length !== 0 && bids.length !== 0 && asks[0][0] <= bids[0][0]) {
|
|
3611
|
+
if (asks.length === 1) {
|
|
3612
|
+
const [price, qty, newQuantity, newAmount] = asks[0];
|
|
3613
|
+
asks.shift();
|
|
3614
|
+
asks.push([
|
|
3615
|
+
price + (depth === void 0 ? 0 : Number(depth)),
|
|
3616
|
+
qty,
|
|
3617
|
+
newQuantity,
|
|
3618
|
+
newAmount
|
|
3619
|
+
]);
|
|
3620
|
+
} else {
|
|
3621
|
+
const [bidPrice] = bids[0];
|
|
3622
|
+
while (asks.length > 0) {
|
|
3623
|
+
const [askPrice, askQty, newQuantity, newAmount] = asks[0];
|
|
3624
|
+
if (askPrice <= bidPrice) {
|
|
3625
|
+
asks.shift();
|
|
3626
|
+
for (let i = 0; i < asks.length; i++) {
|
|
3627
|
+
if (i === 0) {
|
|
3628
|
+
const quantity = new Decimal(asks[i][1]).add(askQty);
|
|
3629
|
+
asks[i][1] = quantity.toNumber();
|
|
3630
|
+
asks[i][2] = quantity.toNumber();
|
|
3631
|
+
asks[i][3] = quantity.toDecimalPlaces(0, Decimal.ROUND_CEIL).mul(asks[i][0]).toNumber();
|
|
3632
|
+
} else {
|
|
3633
|
+
asks[i][3] = new Decimal(asks[i][0]).mul(asks[i][1]).add(asks[i - 1][3]).toNumber();
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3598
3636
|
} else {
|
|
3599
|
-
|
|
3637
|
+
break;
|
|
3600
3638
|
}
|
|
3601
3639
|
}
|
|
3602
|
-
if (index < data.length) {
|
|
3603
|
-
safeRequestIdleCallback(processNextShard, {
|
|
3604
|
-
timeout: 1e3
|
|
3605
|
-
});
|
|
3606
|
-
} else {
|
|
3607
|
-
onComplete(results.flat());
|
|
3608
|
-
}
|
|
3609
3640
|
}
|
|
3610
|
-
safeRequestIdleCallback(processNextShard, {
|
|
3611
|
-
timeout: 1e3
|
|
3612
|
-
});
|
|
3613
3641
|
}
|
|
3642
|
+
asks = asks.reverse();
|
|
3643
|
+
if (padding) {
|
|
3644
|
+
asks = asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks;
|
|
3645
|
+
bids = bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids;
|
|
3646
|
+
}
|
|
3647
|
+
return {
|
|
3648
|
+
asks,
|
|
3649
|
+
bids
|
|
3650
|
+
};
|
|
3614
3651
|
};
|
|
3615
|
-
var
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
maintenance_margin_ratio: 0,
|
|
3620
|
-
open_margin_ratio: 0,
|
|
3621
|
-
current_margin_ratio_with_orders: 0,
|
|
3622
|
-
initial_margin_ratio_with_orders: 0,
|
|
3623
|
-
maintenance_margin_ratio_with_orders: 0,
|
|
3624
|
-
total_collateral_value: 0,
|
|
3625
|
-
free_collateral: 0,
|
|
3626
|
-
total_pnl_24_h: 0,
|
|
3627
|
-
unrealPnL: 0,
|
|
3628
|
-
total_unreal_pnl: 0,
|
|
3629
|
-
unsettledPnL: 0,
|
|
3630
|
-
total_unsettled_pnl: 0,
|
|
3631
|
-
notional: 0,
|
|
3632
|
-
unrealPnlROI: 0
|
|
3652
|
+
var ORDERLY_ORDERBOOK_DEPTH_KEY = "orderly_orderbook_depth_key";
|
|
3653
|
+
var INIT_DATA = {
|
|
3654
|
+
asks: [],
|
|
3655
|
+
bids: []
|
|
3633
3656
|
};
|
|
3634
|
-
var
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
all: POSITION_EMPTY
|
|
3638
|
-
},
|
|
3639
|
-
actions: {
|
|
3640
|
-
setPositions: (key, positions3) => {
|
|
3641
|
-
set((state) => {
|
|
3642
|
-
state.positions[key] = positions3;
|
|
3643
|
-
});
|
|
3644
|
-
},
|
|
3645
|
-
closePosition: (symbol) => {
|
|
3646
|
-
set((state) => {
|
|
3647
|
-
delete state.positions[symbol];
|
|
3648
|
-
});
|
|
3649
|
-
},
|
|
3650
|
-
clearAll: () => {
|
|
3651
|
-
set((state) => {
|
|
3652
|
-
state.positions = {
|
|
3653
|
-
all: POSITION_EMPTY
|
|
3654
|
-
};
|
|
3655
|
-
});
|
|
3656
|
-
}
|
|
3657
|
-
}
|
|
3658
|
-
}))
|
|
3659
|
-
);
|
|
3660
|
-
var usePositions = (symbol = "all") => usePositionStore((state) => (state.positions[symbol] ?? POSITION_EMPTY).rows);
|
|
3661
|
-
var usePositionActions = () => usePositionStore((state) => state.actions);
|
|
3662
|
-
|
|
3663
|
-
// src/orderly/calculator/positions.ts
|
|
3664
|
-
var NAME_PREFIX = "positionCalculator";
|
|
3665
|
-
var AllPositions = "all";
|
|
3666
|
-
var PositionCalculator = class extends BaseCalculator {
|
|
3667
|
-
// private id: string;
|
|
3668
|
-
constructor(symbol = AllPositions) {
|
|
3669
|
-
super();
|
|
3670
|
-
this.name = `${NAME_PREFIX}_${symbol}`;
|
|
3671
|
-
this.symbol = symbol;
|
|
3657
|
+
var useOrderbookStream = (symbol, initial = INIT_DATA, options) => {
|
|
3658
|
+
if (!symbol) {
|
|
3659
|
+
throw new SDKError("Symbol is required");
|
|
3672
3660
|
}
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3661
|
+
const level = options?.level ?? 10;
|
|
3662
|
+
const padding = options?.padding ?? true;
|
|
3663
|
+
const symbolRef = useRef(symbol);
|
|
3664
|
+
symbolRef.current = symbol;
|
|
3665
|
+
const {
|
|
3666
|
+
defaultOrderbookTickSizes: DEFAULT_TICK_SIZES2 = {},
|
|
3667
|
+
defaultOrderbookSymbolDepths: DEFAULT_SYMBOL_DEPTHS2 = {}
|
|
3668
|
+
} = useContext(OrderlyContext);
|
|
3669
|
+
const [data, setData] = useState(initial);
|
|
3670
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
3671
|
+
const config = useSymbolsInfo()[symbol];
|
|
3672
|
+
const [depthObject, setDepthObject] = useLocalStorage(
|
|
3673
|
+
ORDERLY_ORDERBOOK_DEPTH_KEY,
|
|
3674
|
+
{}
|
|
3675
|
+
);
|
|
3676
|
+
const prevMiddlePrice = useRef(0);
|
|
3677
|
+
const tick = config("quote_tick");
|
|
3678
|
+
const depths = useMemo(() => {
|
|
3679
|
+
if (DEFAULT_SYMBOL_DEPTHS2[symbol]) {
|
|
3680
|
+
return DEFAULT_SYMBOL_DEPTHS2[symbol];
|
|
3676
3681
|
}
|
|
3677
|
-
if (
|
|
3678
|
-
return
|
|
3682
|
+
if (typeof tick === "undefined") {
|
|
3683
|
+
return [];
|
|
3679
3684
|
}
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
+
try {
|
|
3686
|
+
const base = new Decimal(tick);
|
|
3687
|
+
return [
|
|
3688
|
+
base.toNumber(),
|
|
3689
|
+
base.mul(10).toNumber(),
|
|
3690
|
+
base.mul(100).toNumber(),
|
|
3691
|
+
base.mul(1e3).toNumber()
|
|
3692
|
+
];
|
|
3693
|
+
} catch {
|
|
3685
3694
|
}
|
|
3686
|
-
return
|
|
3687
|
-
}
|
|
3688
|
-
|
|
3689
|
-
if (
|
|
3695
|
+
return [tick];
|
|
3696
|
+
}, [symbol, tick]);
|
|
3697
|
+
useEffect(() => {
|
|
3698
|
+
if (depthObject[symbol]) {
|
|
3690
3699
|
return;
|
|
3691
|
-
usePositionStore.getState().actions.setPositions(this.symbol, data);
|
|
3692
|
-
if (Array.isArray(data.rows) && useApiStatusStore.getState().apis.positions.loading) {
|
|
3693
|
-
useApiStatusStore.getState().actions.updateApiLoading("positions", false);
|
|
3694
3700
|
}
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
return positions3;
|
|
3701
|
-
positions3 = {
|
|
3702
|
-
...positions3,
|
|
3703
|
-
rows: positions3.rows.map((item) => {
|
|
3704
|
-
return {
|
|
3705
|
-
...item,
|
|
3706
|
-
mark_price: markPrice[item.symbol] || item.mark_price
|
|
3707
|
-
};
|
|
3708
|
-
})
|
|
3709
|
-
};
|
|
3710
|
-
return this.format(positions3, ctx);
|
|
3711
|
-
}
|
|
3712
|
-
calcByIndexPrice(indexPrice, ctx) {
|
|
3713
|
-
let positions3 = this.getPosition(indexPrice, ctx);
|
|
3714
|
-
if (!positions3) {
|
|
3715
|
-
return positions3;
|
|
3716
|
-
}
|
|
3717
|
-
if (!Array.isArray(positions3.rows) || !positions3.rows.length)
|
|
3718
|
-
return positions3;
|
|
3719
|
-
positions3 = {
|
|
3720
|
-
...positions3,
|
|
3721
|
-
rows: positions3.rows.map((item) => ({
|
|
3722
|
-
...item,
|
|
3723
|
-
index_price: indexPrice[item.symbol] || item.index_price || item.mark_price
|
|
3724
|
-
}))
|
|
3725
|
-
};
|
|
3726
|
-
return this.format(positions3, ctx);
|
|
3727
|
-
}
|
|
3728
|
-
calcByPosition(positions3, ctx) {
|
|
3729
|
-
if (positions3.rows.length === 0)
|
|
3730
|
-
return positions3;
|
|
3731
|
-
return this.format(positions3, ctx);
|
|
3732
|
-
}
|
|
3733
|
-
format(data, ctx) {
|
|
3734
|
-
const { accountInfo, symbolsInfo, fundingRates, portfolio } = ctx;
|
|
3735
|
-
if (!accountInfo || !fundingRates || !symbolsInfo) {
|
|
3736
|
-
return data;
|
|
3737
|
-
}
|
|
3738
|
-
let unrealPnL_total = zero, unrealPnL_total_index = zero, notional_total = zero, unsettlementPnL_total = zero;
|
|
3739
|
-
let rows = data.rows.map((item) => {
|
|
3740
|
-
const info = symbolsInfo[item.symbol];
|
|
3741
|
-
const sum_unitary_funding = fundingRates?.[item.symbol]?.["sum_unitary_funding"] ?? 0;
|
|
3742
|
-
const notional = positions.notional(item.position_qty, item.mark_price);
|
|
3743
|
-
const unrealPnl = positions.unrealizedPnL({
|
|
3744
|
-
qty: item.position_qty,
|
|
3745
|
-
openPrice: item?.average_open_price,
|
|
3746
|
-
// markPrice: unRealizedPrice,
|
|
3747
|
-
markPrice: item.mark_price
|
|
3748
|
-
});
|
|
3749
|
-
let unrealPnl_index = 0, unrealPnlROI_index = 0;
|
|
3750
|
-
const maxLeverage = item.leverage || 1;
|
|
3751
|
-
const imr = account.IMR({
|
|
3752
|
-
maxLeverage,
|
|
3753
|
-
baseIMR: info?.["base_imr"],
|
|
3754
|
-
IMR_Factor: accountInfo.imr_factor[item.symbol],
|
|
3755
|
-
positionNotional: notional,
|
|
3756
|
-
ordersNotional: 0,
|
|
3757
|
-
IMR_factor_power: 4 / 5
|
|
3758
|
-
});
|
|
3759
|
-
const unrealPnlROI = positions.unrealizedPnLROI({
|
|
3760
|
-
positionQty: item.position_qty,
|
|
3761
|
-
openPrice: item.average_open_price,
|
|
3762
|
-
IMR: imr,
|
|
3763
|
-
unrealizedPnL: unrealPnl
|
|
3764
|
-
});
|
|
3765
|
-
if (item.index_price) {
|
|
3766
|
-
unrealPnl_index = positions.unrealizedPnL({
|
|
3767
|
-
qty: item.position_qty,
|
|
3768
|
-
openPrice: item?.average_open_price,
|
|
3769
|
-
// markPrice: unRealizedPrice,
|
|
3770
|
-
markPrice: item.index_price
|
|
3771
|
-
});
|
|
3772
|
-
unrealPnlROI_index = positions.unrealizedPnLROI({
|
|
3773
|
-
positionQty: item.position_qty,
|
|
3774
|
-
openPrice: item.average_open_price,
|
|
3775
|
-
IMR: imr,
|
|
3776
|
-
unrealizedPnL: unrealPnl_index
|
|
3777
|
-
});
|
|
3778
|
-
}
|
|
3779
|
-
const unsettlementPnL2 = positions.unsettlementPnL({
|
|
3780
|
-
positionQty: item.position_qty,
|
|
3781
|
-
markPrice: item.mark_price,
|
|
3782
|
-
costPosition: item.cost_position,
|
|
3783
|
-
sumUnitaryFunding: propOr(
|
|
3784
|
-
0,
|
|
3785
|
-
"sum_unitary_funding",
|
|
3786
|
-
fundingRates[item.symbol]
|
|
3787
|
-
),
|
|
3788
|
-
lastSumUnitaryFunding: item.last_sum_unitary_funding
|
|
3789
|
-
});
|
|
3790
|
-
const MMR = positions.MMR({
|
|
3791
|
-
baseMMR: info?.["base_mmr"],
|
|
3792
|
-
baseIMR: info?.["base_imr"],
|
|
3793
|
-
IMRFactor: accountInfo.imr_factor[item.symbol],
|
|
3794
|
-
positionNotional: notional,
|
|
3795
|
-
IMR_factor_power: 4 / 5
|
|
3796
|
-
});
|
|
3797
|
-
unrealPnL_total = unrealPnL_total.add(unrealPnl);
|
|
3798
|
-
unrealPnL_total_index = unrealPnL_total_index.add(unrealPnl_index);
|
|
3799
|
-
notional_total = notional_total.add(notional);
|
|
3800
|
-
unsettlementPnL_total = unsettlementPnL_total.add(unsettlementPnL2);
|
|
3801
|
-
const fundingFee = new Decimal(sum_unitary_funding).sub(item.last_sum_unitary_funding).mul(item.position_qty).negated().toNumber();
|
|
3802
|
-
return {
|
|
3803
|
-
...item,
|
|
3804
|
-
fundingFee,
|
|
3805
|
-
mm: positions.maintenanceMargin({
|
|
3806
|
-
positionQty: item.position_qty,
|
|
3807
|
-
markPrice: item.mark_price,
|
|
3808
|
-
MMR
|
|
3809
|
-
}),
|
|
3810
|
-
mmr: MMR,
|
|
3811
|
-
notional,
|
|
3812
|
-
unsettlement_pnl: unsettlementPnL2,
|
|
3813
|
-
unrealized_pnl: unrealPnl,
|
|
3814
|
-
unrealized_pnl_index: unrealPnl_index,
|
|
3815
|
-
unrealized_pnl_ROI: unrealPnlROI,
|
|
3816
|
-
unrealized_pnl_ROI_index: unrealPnlROI_index
|
|
3817
|
-
};
|
|
3818
|
-
});
|
|
3819
|
-
const totalUnrealPnl = unrealPnL_total.toNumber();
|
|
3820
|
-
const totalUnrealPnl_index = unrealPnL_total_index.toNumber();
|
|
3821
|
-
const unsettlementPnL = unsettlementPnL_total.toNumber();
|
|
3822
|
-
let totalUnrealizedROI = 0, totalUnrealizedROI_index = 0;
|
|
3823
|
-
if (portfolio) {
|
|
3824
|
-
const { totalValue, totalCollateral } = portfolio;
|
|
3825
|
-
rows = rows.map((item) => {
|
|
3826
|
-
const est_liq_price = positions.liqPrice({
|
|
3827
|
-
markPrice: item.mark_price,
|
|
3828
|
-
totalCollateral: totalCollateral.toNumber(),
|
|
3829
|
-
positionQty: item.position_qty,
|
|
3830
|
-
positions: rows,
|
|
3831
|
-
MMR: item.mmr
|
|
3832
|
-
});
|
|
3833
|
-
return {
|
|
3834
|
-
...item,
|
|
3835
|
-
est_liq_price
|
|
3836
|
-
};
|
|
3837
|
-
});
|
|
3838
|
-
if (totalValue !== null && !totalValue.eq(zero)) {
|
|
3839
|
-
totalUnrealizedROI = account.totalUnrealizedROI({
|
|
3840
|
-
totalUnrealizedPnL: totalUnrealPnl,
|
|
3841
|
-
totalValue: totalValue.toNumber()
|
|
3842
|
-
});
|
|
3843
|
-
totalUnrealizedROI_index = account.totalUnrealizedROI({
|
|
3844
|
-
totalUnrealizedPnL: totalUnrealPnl_index,
|
|
3845
|
-
totalValue: totalValue.toNumber()
|
|
3846
|
-
});
|
|
3847
|
-
}
|
|
3848
|
-
}
|
|
3849
|
-
return {
|
|
3850
|
-
...data,
|
|
3851
|
-
unrealPnL: totalUnrealPnl,
|
|
3852
|
-
total_unreal_pnl: totalUnrealPnl,
|
|
3853
|
-
total_unreal_pnl_index: totalUnrealPnl_index,
|
|
3854
|
-
notional: notional_total.toNumber(),
|
|
3855
|
-
unsettledPnL: unsettlementPnL,
|
|
3856
|
-
total_unsettled_pnl: unsettlementPnL,
|
|
3857
|
-
unrealPnlROI: totalUnrealizedROI,
|
|
3858
|
-
unrealPnlROI_index: totalUnrealizedROI_index,
|
|
3859
|
-
rows
|
|
3860
|
-
};
|
|
3861
|
-
}
|
|
3862
|
-
preprocess(data) {
|
|
3863
|
-
let rows = data.rows;
|
|
3864
|
-
if (this.symbol !== AllPositions && Array.isArray(rows)) {
|
|
3865
|
-
rows = rows.filter((item) => item.symbol === this.symbol);
|
|
3866
|
-
}
|
|
3867
|
-
return {
|
|
3868
|
-
...data,
|
|
3869
|
-
rows
|
|
3870
|
-
};
|
|
3871
|
-
}
|
|
3872
|
-
getPosition(_, ctx) {
|
|
3873
|
-
const positions3 = ctx.get((output) => output[this.name]) || usePositionStore.getState().positions[this.symbol];
|
|
3874
|
-
if (this.symbol === AllPositions) {
|
|
3875
|
-
return positions3;
|
|
3876
|
-
}
|
|
3877
|
-
if (positions3 && Array.isArray(positions3.rows)) {
|
|
3878
|
-
return positions3;
|
|
3879
|
-
}
|
|
3880
|
-
return this.preprocess(this.getAllPositions(ctx));
|
|
3881
|
-
}
|
|
3882
|
-
destroy() {
|
|
3883
|
-
usePositionStore.getState().actions.closePosition(this.symbol);
|
|
3884
|
-
CalculatorContext.instance?.deleteByName(this.name);
|
|
3885
|
-
}
|
|
3886
|
-
getAllPositions(ctx) {
|
|
3887
|
-
return ctx.get((output) => output[AllPositions]) || usePositionStore.getState().positions[AllPositions];
|
|
3888
|
-
}
|
|
3889
|
-
};
|
|
3890
|
-
PositionCalculator.logPosition = (symbol = "all") => {
|
|
3891
|
-
return usePositionStore.getState().positions[symbol];
|
|
3892
|
-
};
|
|
3893
|
-
var parseHolding = (holding, indexPrices, tokensInfo) => {
|
|
3894
|
-
const nonUSDC = [];
|
|
3895
|
-
let USDC_holding = 0;
|
|
3896
|
-
holding.forEach((item) => {
|
|
3897
|
-
if (item.token === "USDC") {
|
|
3898
|
-
USDC_holding = item.holding;
|
|
3899
|
-
} else {
|
|
3900
|
-
const tokenInfo = tokensInfo.find(({ token }) => token === item.token);
|
|
3901
|
-
const {
|
|
3902
|
-
base_weight = 0,
|
|
3903
|
-
discount_factor = 0,
|
|
3904
|
-
user_max_qty = 0
|
|
3905
|
-
} = tokenInfo || {};
|
|
3906
|
-
const holdingQty = item?.holding ?? 0;
|
|
3907
|
-
const indexPrice = indexPrices[`PERP_${item.token}_USDC`] ?? 0;
|
|
3908
|
-
const collateralRatio4 = account.collateralRatio({
|
|
3909
|
-
baseWeight: base_weight,
|
|
3910
|
-
discountFactor: discount_factor,
|
|
3911
|
-
collateralQty: holdingQty,
|
|
3912
|
-
collateralCap: user_max_qty,
|
|
3913
|
-
indexPrice
|
|
3914
|
-
});
|
|
3915
|
-
nonUSDC.push({
|
|
3916
|
-
holding: holdingQty,
|
|
3917
|
-
indexPrice,
|
|
3918
|
-
collateralCap: user_max_qty,
|
|
3919
|
-
collateralRatio: collateralRatio4
|
|
3920
|
-
});
|
|
3921
|
-
}
|
|
3922
|
-
});
|
|
3923
|
-
return [USDC_holding, nonUSDC];
|
|
3924
|
-
};
|
|
3925
|
-
var useIndexPriceStore = create((set) => ({
|
|
3926
|
-
indexPrices: {},
|
|
3927
|
-
actions: {
|
|
3928
|
-
updateIndexPrice: (indexPrice) => {
|
|
3929
|
-
set({
|
|
3930
|
-
indexPrices: indexPrice
|
|
3931
|
-
});
|
|
3932
|
-
}
|
|
3933
|
-
}
|
|
3934
|
-
}));
|
|
3935
|
-
|
|
3936
|
-
// src/orderly/calculator/indexPrice.ts
|
|
3937
|
-
var IndexPriceCalculatorName = "indexPriceCalculator";
|
|
3938
|
-
var IndexPriceCalculator = class extends BaseCalculator {
|
|
3939
|
-
constructor() {
|
|
3940
|
-
super(...arguments);
|
|
3941
|
-
this.name = IndexPriceCalculatorName;
|
|
3942
|
-
}
|
|
3943
|
-
calc(scope, data, ctx) {
|
|
3944
|
-
return data;
|
|
3945
|
-
}
|
|
3946
|
-
update(data) {
|
|
3947
|
-
if (!data)
|
|
3948
|
-
return;
|
|
3949
|
-
useIndexPriceStore.getState().actions.updateIndexPrice(data);
|
|
3950
|
-
}
|
|
3951
|
-
static getValue() {
|
|
3952
|
-
return useIndexPriceStore.getState().indexPrices;
|
|
3953
|
-
}
|
|
3954
|
-
};
|
|
3955
|
-
|
|
3956
|
-
// src/orderly/calculator/portfolio.ts
|
|
3957
|
-
var PortfolioCalculatorName = "portfolio";
|
|
3958
|
-
var PortfolioCalculator = class extends BaseCalculator {
|
|
3959
|
-
constructor() {
|
|
3960
|
-
super(...arguments);
|
|
3961
|
-
this.name = PortfolioCalculatorName;
|
|
3962
|
-
}
|
|
3963
|
-
calc(scope, data, ctx) {
|
|
3964
|
-
let markPrices;
|
|
3965
|
-
let indexPrices;
|
|
3966
|
-
const portfolio = this.getPortfolio(ctx);
|
|
3967
|
-
if (scope === "markPrice" /* MARK_PRICE */) {
|
|
3968
|
-
markPrices = data;
|
|
3969
|
-
} else {
|
|
3970
|
-
markPrices = ctx.get(
|
|
3971
|
-
(cache) => cache[MarketCalculatorName]
|
|
3972
|
-
);
|
|
3973
|
-
}
|
|
3974
|
-
if (scope === "indexPrice" /* INDEX_PRICE */) {
|
|
3975
|
-
indexPrices = data;
|
|
3701
|
+
if (DEFAULT_TICK_SIZES2[symbol]) {
|
|
3702
|
+
setDepthObject((prev) => ({
|
|
3703
|
+
...prev,
|
|
3704
|
+
[symbol]: Number(DEFAULT_TICK_SIZES2[symbol])
|
|
3705
|
+
}));
|
|
3976
3706
|
} else {
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3707
|
+
setDepthObject((prev) => ({
|
|
3708
|
+
...prev,
|
|
3709
|
+
[symbol]: tick
|
|
3710
|
+
}));
|
|
3980
3711
|
}
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
)
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3712
|
+
}, [depthObject, tick, symbol, DEFAULT_TICK_SIZES2]);
|
|
3713
|
+
const onDepthChange = useCallback(
|
|
3714
|
+
(val) => {
|
|
3715
|
+
setDepthObject((prev) => ({ ...prev, [symbol]: val }));
|
|
3716
|
+
},
|
|
3717
|
+
[symbol]
|
|
3718
|
+
);
|
|
3719
|
+
const ws = useWS();
|
|
3720
|
+
const ticker = useTickerStream(symbol);
|
|
3721
|
+
const eventEmitter = useEventEmitter();
|
|
3722
|
+
useEffect(() => {
|
|
3723
|
+
let needRequestFullOrderbook = true;
|
|
3724
|
+
setIsLoading(true);
|
|
3725
|
+
let fullOrderBookUpdateSub;
|
|
3726
|
+
const orderBookUpdateSub = ws.subscribe(
|
|
3727
|
+
{
|
|
3728
|
+
event: "subscribe",
|
|
3729
|
+
topic: `${symbol}@orderbookupdate`
|
|
3730
|
+
},
|
|
3731
|
+
{
|
|
3732
|
+
formatter: (message) => message,
|
|
3733
|
+
onMessage: (message) => {
|
|
3734
|
+
const { data: wsData, ts } = message;
|
|
3735
|
+
const { symbol: symbol2, asks, bids, prevTs } = wsData;
|
|
3736
|
+
if (symbolRef.current !== symbol2) {
|
|
3737
|
+
orderBookUpdateSub?.();
|
|
3738
|
+
return;
|
|
3996
3739
|
}
|
|
3997
|
-
|
|
3998
|
-
|
|
3740
|
+
orderbook_service_default.updateOrderbook(
|
|
3741
|
+
symbol2,
|
|
3742
|
+
{ asks, bids, ts, prevTs },
|
|
3743
|
+
() => {
|
|
3744
|
+
needRequestFullOrderbook = true;
|
|
3745
|
+
}
|
|
3746
|
+
);
|
|
3747
|
+
const data2 = orderbook_service_default.getRawOrderbook(symbol2);
|
|
3748
|
+
setData({ bids: data2.bids, asks: data2.asks });
|
|
3749
|
+
}
|
|
3999
3750
|
}
|
|
4000
|
-
}
|
|
4001
|
-
const accountInfo = ctx.accountInfo;
|
|
4002
|
-
const symbolsInfo = ctx.symbolsInfo;
|
|
4003
|
-
const tokensInfo = ctx.tokensInfo;
|
|
4004
|
-
return this.format({
|
|
4005
|
-
holding,
|
|
4006
|
-
positions: positions3,
|
|
4007
|
-
markPrices,
|
|
4008
|
-
accountInfo,
|
|
4009
|
-
symbolsInfo,
|
|
4010
|
-
indexPrices,
|
|
4011
|
-
tokensInfo: tokensInfo ?? EMPTY_LIST
|
|
4012
|
-
});
|
|
4013
|
-
}
|
|
4014
|
-
getPortfolio(ctx) {
|
|
4015
|
-
return ctx.get((output) => output[this.name]) || useAppStore.getState().portfolio;
|
|
4016
|
-
}
|
|
4017
|
-
format(inputs) {
|
|
4018
|
-
const {
|
|
4019
|
-
holding,
|
|
4020
|
-
positions: positions3,
|
|
4021
|
-
markPrices,
|
|
4022
|
-
indexPrices,
|
|
4023
|
-
accountInfo,
|
|
4024
|
-
symbolsInfo,
|
|
4025
|
-
tokensInfo
|
|
4026
|
-
} = inputs;
|
|
4027
|
-
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo) {
|
|
4028
|
-
return null;
|
|
4029
|
-
}
|
|
4030
|
-
const unsettledPnL = pathOr(0, ["total_unsettled_pnl"])(positions3);
|
|
4031
|
-
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
4032
|
-
const [USDC_holding, nonUSDC] = parseHolding(
|
|
4033
|
-
holding,
|
|
4034
|
-
indexPrices,
|
|
4035
|
-
tokensInfo
|
|
4036
3751
|
);
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
totalValue,
|
|
4070
|
-
totalUnrealizedROI,
|
|
4071
|
-
freeCollateral,
|
|
4072
|
-
availableBalance,
|
|
4073
|
-
unsettledPnL,
|
|
4074
|
-
holding
|
|
3752
|
+
if (needRequestFullOrderbook) {
|
|
3753
|
+
setIsLoading(true);
|
|
3754
|
+
fullOrderBookUpdateSub = ws.onceSubscribe(
|
|
3755
|
+
{
|
|
3756
|
+
event: "request",
|
|
3757
|
+
id: `${symbol}@orderbook`,
|
|
3758
|
+
params: {
|
|
3759
|
+
type: "orderbook",
|
|
3760
|
+
symbol
|
|
3761
|
+
}
|
|
3762
|
+
},
|
|
3763
|
+
{
|
|
3764
|
+
formatter: (message) => message,
|
|
3765
|
+
onMessage: (message) => {
|
|
3766
|
+
const { symbol: symbol2, asks, bids, ts } = message.data;
|
|
3767
|
+
if (symbolRef.current !== symbol2) {
|
|
3768
|
+
return;
|
|
3769
|
+
}
|
|
3770
|
+
orderbook_service_default.setFullOrderbook(symbol2, { asks, bids, ts });
|
|
3771
|
+
const data2 = orderbook_service_default.getRawOrderbook(symbol2);
|
|
3772
|
+
setData({ bids: data2.bids, asks: data2.asks });
|
|
3773
|
+
setIsLoading(false);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
);
|
|
3777
|
+
needRequestFullOrderbook = false;
|
|
3778
|
+
}
|
|
3779
|
+
return () => {
|
|
3780
|
+
orderBookUpdateSub?.();
|
|
3781
|
+
fullOrderBookUpdateSub?.();
|
|
3782
|
+
orderbook_service_default.resetOrderBook(symbol);
|
|
3783
|
+
setData(INIT_DATA);
|
|
4075
3784
|
};
|
|
4076
|
-
}
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
3785
|
+
}, [symbol]);
|
|
3786
|
+
const { data: markPrice } = useMarkPrice(symbol);
|
|
3787
|
+
const onItemClick = useCallback((item) => {
|
|
3788
|
+
eventEmitter.emit("orderbook:item:click", item);
|
|
3789
|
+
}, []);
|
|
3790
|
+
const reducedData = reduceOrderbook(depthObject[symbol], level, padding, {
|
|
3791
|
+
asks: data.asks,
|
|
3792
|
+
bids: data.bids
|
|
3793
|
+
});
|
|
3794
|
+
useEffect(() => {
|
|
3795
|
+
eventEmitter.emit("orderbook:update", reducedData);
|
|
3796
|
+
}, [reducedData]);
|
|
3797
|
+
const middlePrice = useMemo(() => {
|
|
3798
|
+
let asksFrist = 0;
|
|
3799
|
+
let bidsFirst = 0;
|
|
3800
|
+
if (data.asks.length > 0) {
|
|
3801
|
+
asksFrist = reducedData.asks?.[reducedData.asks.length - 1]?.[0];
|
|
4088
3802
|
}
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
// src/useCalculatorService.ts
|
|
4093
|
-
var useCalculatorService = () => {
|
|
4094
|
-
const { get: get3 } = useSimpleDI();
|
|
4095
|
-
const calculatorService = useConstant(() => {
|
|
4096
|
-
let calculatorService2 = get3(CalculatorServiceID);
|
|
4097
|
-
if (!calculatorService2) {
|
|
4098
|
-
const positionCalculator = new PositionCalculator();
|
|
4099
|
-
const portfolioCalculator = new PortfolioCalculator();
|
|
4100
|
-
const markPriceCalculator = new MarkPriceCalculator();
|
|
4101
|
-
const indexPriceCalculator = new IndexPriceCalculator();
|
|
4102
|
-
calculatorService2 = new CalculatorService(new ShardingScheduler(), [
|
|
4103
|
-
[
|
|
4104
|
-
"markPrice" /* MARK_PRICE */,
|
|
4105
|
-
[
|
|
4106
|
-
markPriceCalculator,
|
|
4107
|
-
positionCalculator,
|
|
4108
|
-
portfolioCalculator,
|
|
4109
|
-
positionCalculator
|
|
4110
|
-
]
|
|
4111
|
-
],
|
|
4112
|
-
["position" /* POSITION */, [positionCalculator, portfolioCalculator]],
|
|
4113
|
-
["portfolio" /* PORTFOLIO */, [portfolioCalculator]],
|
|
4114
|
-
// indexPrice
|
|
4115
|
-
[
|
|
4116
|
-
"indexPrice" /* INDEX_PRICE */,
|
|
4117
|
-
[indexPriceCalculator, positionCalculator]
|
|
4118
|
-
]
|
|
4119
|
-
]);
|
|
4120
|
-
SimpleDI.registerByName(CalculatorServiceID, calculatorService2);
|
|
3803
|
+
if (data.bids.length > 0) {
|
|
3804
|
+
bidsFirst = data.bids[0][0];
|
|
4121
3805
|
}
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
return calculatorService;
|
|
4125
|
-
};
|
|
4126
|
-
|
|
4127
|
-
// src/orderly/orderbook.service.ts
|
|
4128
|
-
var defaultRawOrderBook = {
|
|
4129
|
-
asks: [],
|
|
4130
|
-
bids: [],
|
|
4131
|
-
ts: 0
|
|
4132
|
-
};
|
|
4133
|
-
var OrderbookService = class _OrderbookService {
|
|
4134
|
-
constructor() {
|
|
4135
|
-
this.bufferedOrderBookUpdates = {};
|
|
4136
|
-
this.rawOrderBook = {};
|
|
4137
|
-
}
|
|
4138
|
-
static getInstance() {
|
|
4139
|
-
if (!this.instance) {
|
|
4140
|
-
this.instance = new _OrderbookService();
|
|
3806
|
+
if (!isNumber(asksFrist) || !isNumber(bidsFirst) || !ticker) {
|
|
3807
|
+
return 0;
|
|
4141
3808
|
}
|
|
4142
|
-
return
|
|
4143
|
-
}
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
}
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
3809
|
+
return [asksFrist, bidsFirst, ticker["24h_close"]].sort()[1];
|
|
3810
|
+
}, [ticker?.["24h_close"], data]);
|
|
3811
|
+
useEffect(() => {
|
|
3812
|
+
prevMiddlePrice.current = middlePrice;
|
|
3813
|
+
}, [middlePrice]);
|
|
3814
|
+
return [
|
|
3815
|
+
{
|
|
3816
|
+
asks: reducedData.asks.slice(-level),
|
|
3817
|
+
bids: reducedData.bids.slice(0, level),
|
|
3818
|
+
markPrice,
|
|
3819
|
+
middlePrice: [prevMiddlePrice.current, middlePrice]
|
|
3820
|
+
},
|
|
3821
|
+
{
|
|
3822
|
+
onDepthChange,
|
|
3823
|
+
depth: depthObject[symbol],
|
|
3824
|
+
allDepths: depths,
|
|
3825
|
+
isLoading,
|
|
3826
|
+
onItemClick
|
|
4151
3827
|
}
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
}
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
3828
|
+
];
|
|
3829
|
+
};
|
|
3830
|
+
var useSymbolInfo = (symbol) => {
|
|
3831
|
+
const infos = useSymbolsInfo();
|
|
3832
|
+
return useMemo(() => {
|
|
3833
|
+
return !symbol || infos.isNil ? null : infos[symbol];
|
|
3834
|
+
}, [infos, symbol]);
|
|
3835
|
+
};
|
|
3836
|
+
var useFundingRates = () => {
|
|
3837
|
+
const data = useAppStore((state) => state.fundingRates);
|
|
3838
|
+
return createGetter({ ...data });
|
|
3839
|
+
};
|
|
3840
|
+
var useFundingRatesStore = () => {
|
|
3841
|
+
const data = useAppStore((state) => state.fundingRates);
|
|
3842
|
+
return data;
|
|
3843
|
+
};
|
|
3844
|
+
|
|
3845
|
+
// src/orderly/useMarket.ts
|
|
3846
|
+
var DefaultTab = { name: "Popular", id: 1 };
|
|
3847
|
+
var marketsKey = "markets";
|
|
3848
|
+
var useMarket = (type) => {
|
|
3849
|
+
const { configStore } = useContext(OrderlyContext);
|
|
3850
|
+
const symbolsInfo = useSymbolsInfo();
|
|
3851
|
+
const fundingRates = useFundingRates();
|
|
3852
|
+
const { data: futures } = useMarketsStream();
|
|
3853
|
+
const updateStore = (key, data) => {
|
|
3854
|
+
configStore.set(marketsKey, {
|
|
3855
|
+
...configStore.getOr(marketsKey, {}),
|
|
3856
|
+
[key]: data
|
|
4177
3857
|
});
|
|
4178
|
-
}
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
}
|
|
4182
|
-
|
|
4183
|
-
const
|
|
4184
|
-
if (
|
|
4185
|
-
|
|
3858
|
+
};
|
|
3859
|
+
const getStore = (key, defaultValue) => {
|
|
3860
|
+
return configStore.get(marketsKey)[key] || defaultValue;
|
|
3861
|
+
};
|
|
3862
|
+
if (!configStore.get(marketsKey)) {
|
|
3863
|
+
const jsonStr = localStorage.getItem(marketsKey);
|
|
3864
|
+
if (jsonStr) {
|
|
3865
|
+
configStore.set(marketsKey, JSON.parse(jsonStr));
|
|
3866
|
+
} else {
|
|
3867
|
+
configStore.set(marketsKey, {
|
|
3868
|
+
recent: [],
|
|
3869
|
+
favorites: [
|
|
3870
|
+
{ name: "PERP_ETH_USDC", tabs: [{ ...DefaultTab }] },
|
|
3871
|
+
{ name: "PERP_BTC_USDC", tabs: [{ ...DefaultTab }] }
|
|
3872
|
+
],
|
|
3873
|
+
favoriteTabs: [{ ...DefaultTab }],
|
|
3874
|
+
lastSelectedFavoriteTab: { ...DefaultTab }
|
|
3875
|
+
});
|
|
4186
3876
|
}
|
|
4187
3877
|
}
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
const
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
3878
|
+
const getFavoriteTabs = useMemo(() => {
|
|
3879
|
+
return getStore("favoriteTabs", [{ ...DefaultTab }]);
|
|
3880
|
+
}, []);
|
|
3881
|
+
const getFavorites = useMemo(() => {
|
|
3882
|
+
const curData = getStore("favorites", []);
|
|
3883
|
+
const tabs = getFavoriteTabs;
|
|
3884
|
+
const result = [];
|
|
3885
|
+
const len = curData.length;
|
|
3886
|
+
for (let index = 0; index < len; index++) {
|
|
3887
|
+
const favData = curData[index];
|
|
3888
|
+
const favTabs = favData.tabs.filter(
|
|
3889
|
+
(tab) => tabs.findIndex((item) => tab.id === item.id) !== -1
|
|
3890
|
+
);
|
|
3891
|
+
if (favTabs.length) {
|
|
3892
|
+
result.push({ ...favData, tabs: favTabs });
|
|
4197
3893
|
}
|
|
4198
3894
|
}
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
}
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
const { asks, bids, prevTs, ts } = update;
|
|
4218
|
-
const rawOrderBook = this.rawOrderBook[symbol];
|
|
4219
|
-
if (!rawOrderBook) {
|
|
4220
|
-
return;
|
|
4221
|
-
}
|
|
4222
|
-
const currentTs = rawOrderBook.ts;
|
|
4223
|
-
if (currentTs === 0) {
|
|
4224
|
-
this.pushUpdateToBuffer(symbol, { asks, bids, prevTs, ts });
|
|
3895
|
+
updateStore("favorites", result);
|
|
3896
|
+
return result;
|
|
3897
|
+
}, [configStore]);
|
|
3898
|
+
const [favoriteTabs, setFavoriteTabs] = useState(getFavoriteTabs);
|
|
3899
|
+
const [favorites, setFavorites] = useState(getFavorites);
|
|
3900
|
+
const [recent, setRecent] = useState(
|
|
3901
|
+
getStore("recent", []).filter((e) => e)
|
|
3902
|
+
);
|
|
3903
|
+
const [tabSort, setTabSort] = useState(
|
|
3904
|
+
getStore("tabSort", {})
|
|
3905
|
+
);
|
|
3906
|
+
const updateFavoriteTabs = (tab, operator) => {
|
|
3907
|
+
const saveTabs = (tabs2) => {
|
|
3908
|
+
setFavoriteTabs(tabs2);
|
|
3909
|
+
updateStore("favoriteTabs", tabs2);
|
|
3910
|
+
};
|
|
3911
|
+
if (Array.isArray(tab)) {
|
|
3912
|
+
saveTabs(tab);
|
|
4225
3913
|
return;
|
|
4226
3914
|
}
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
3915
|
+
const tabs = [...favoriteTabs];
|
|
3916
|
+
const index = tabs.findIndex((item) => item.id === tab.id);
|
|
3917
|
+
if (operator?.add) {
|
|
3918
|
+
tabs.push(tab);
|
|
3919
|
+
} else if (operator?.update) {
|
|
3920
|
+
if (index !== -1) {
|
|
3921
|
+
tabs[index] = tab;
|
|
3922
|
+
}
|
|
3923
|
+
} else if (operator?.delete) {
|
|
3924
|
+
if (index !== -1) {
|
|
3925
|
+
tabs.splice(index, 1);
|
|
4231
3926
|
}
|
|
4232
|
-
return;
|
|
4233
3927
|
}
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
}
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
3928
|
+
saveTabs(tabs);
|
|
3929
|
+
};
|
|
3930
|
+
const updateFavorites = (favorites2) => {
|
|
3931
|
+
updateStore("favorites", favorites2);
|
|
3932
|
+
setFavorites(favorites2);
|
|
3933
|
+
};
|
|
3934
|
+
const addToHistory = (symbol) => {
|
|
3935
|
+
const curData = [...recent];
|
|
3936
|
+
const index = curData.findIndex((item) => item.name == symbol.symbol);
|
|
3937
|
+
if (index !== -1) {
|
|
3938
|
+
curData.splice(index, 1);
|
|
3939
|
+
}
|
|
3940
|
+
curData.unshift({ name: symbol.symbol });
|
|
3941
|
+
updateStore("recent", curData);
|
|
3942
|
+
setRecent(curData);
|
|
3943
|
+
};
|
|
3944
|
+
const updateSymbolFavoriteState = (symbol, tab, remove = false) => {
|
|
3945
|
+
const curData = [...favorites];
|
|
3946
|
+
const index = curData.findIndex((item) => item.name == symbol.symbol);
|
|
3947
|
+
if (index === -1) {
|
|
3948
|
+
if (Array.isArray(tab)) {
|
|
3949
|
+
if (tab.length > 0) {
|
|
3950
|
+
curData.unshift({ name: symbol.symbol, tabs: tab });
|
|
3951
|
+
}
|
|
3952
|
+
} else {
|
|
3953
|
+
if (!remove) {
|
|
3954
|
+
curData.unshift({ name: symbol.symbol, tabs: [tab] });
|
|
3955
|
+
}
|
|
4253
3956
|
}
|
|
4254
|
-
}
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
};
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
3957
|
+
} else {
|
|
3958
|
+
const favorite = curData[index];
|
|
3959
|
+
if (Array.isArray(tab)) {
|
|
3960
|
+
if (tab.length === 0) {
|
|
3961
|
+
curData.splice(index, 1);
|
|
3962
|
+
} else {
|
|
3963
|
+
curData[index] = { ...favorite, tabs: tab };
|
|
3964
|
+
}
|
|
3965
|
+
} else {
|
|
3966
|
+
if (remove) {
|
|
3967
|
+
const tabs = favorite.tabs.filter((item) => item.id != tab.id);
|
|
3968
|
+
if (tabs.length === 0) {
|
|
3969
|
+
curData.splice(index, 1);
|
|
3970
|
+
} else {
|
|
3971
|
+
curData[index] = { ...favorite, tabs };
|
|
3972
|
+
}
|
|
3973
|
+
} else {
|
|
3974
|
+
const tabs = favorite.tabs;
|
|
3975
|
+
tabs.push(tab);
|
|
3976
|
+
curData[index] = { ...favorite, tabs };
|
|
3977
|
+
}
|
|
4268
3978
|
}
|
|
3979
|
+
}
|
|
3980
|
+
updateStore("favorites", curData);
|
|
3981
|
+
setFavorites(() => curData);
|
|
3982
|
+
};
|
|
3983
|
+
const marketsList = useMemo(() => {
|
|
3984
|
+
const list = futures?.map((item) => {
|
|
3985
|
+
const { open_interest = 0, index_price = 0 } = item;
|
|
3986
|
+
const info = symbolsInfo[item.symbol];
|
|
3987
|
+
const rate = fundingRates[item.symbol];
|
|
3988
|
+
const est_funding_rate = rate("est_funding_rate");
|
|
3989
|
+
const funding_period = info("funding_period");
|
|
3990
|
+
const change = item.change === void 0 ? get24hChange2(item["24h_close"], item["24h_open"]) : item.change;
|
|
3991
|
+
return {
|
|
3992
|
+
...item,
|
|
3993
|
+
change,
|
|
3994
|
+
"8h_funding": get8hFunding2(est_funding_rate, funding_period),
|
|
3995
|
+
quote_dp: info("quote_dp"),
|
|
3996
|
+
created_time: info("created_time"),
|
|
3997
|
+
openInterest: new Decimal(open_interest || 0).mul(index_price || 0).toNumber()
|
|
3998
|
+
};
|
|
4269
3999
|
});
|
|
4270
|
-
return
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4000
|
+
return list || [];
|
|
4001
|
+
}, [symbolsInfo, futures, fundingRates]);
|
|
4002
|
+
const getData = (type2) => {
|
|
4003
|
+
const localData = type2 === 0 /* FAVORITES */ ? [...favorites] : [...recent];
|
|
4004
|
+
const keys = localData.map((item) => item.name);
|
|
4005
|
+
const filter = type2 == 2 /* ALL */ ? marketsList : marketsList?.filter((item) => keys.includes(item.symbol));
|
|
4006
|
+
const favoritesData = [...favorites];
|
|
4007
|
+
const favoriteKeys = favoritesData.map((item) => item.name);
|
|
4008
|
+
if (filter) {
|
|
4009
|
+
for (let index = 0; index < filter.length; index++) {
|
|
4010
|
+
const element = filter[index];
|
|
4011
|
+
const isFavorite = type2 == 0 /* FAVORITES */ ? true : favoriteKeys.includes(element.symbol);
|
|
4012
|
+
const fIndex = favoritesData.findIndex(
|
|
4013
|
+
(item) => item.name === element.symbol
|
|
4014
|
+
);
|
|
4015
|
+
const tabs = fIndex === -1 ? [] : favoritesData[fIndex].tabs;
|
|
4016
|
+
let imr = void 0;
|
|
4017
|
+
if (symbolsInfo) {
|
|
4018
|
+
imr = symbolsInfo?.[element.symbol]("base_imr");
|
|
4019
|
+
}
|
|
4020
|
+
filter[index] = {
|
|
4021
|
+
...filter[index],
|
|
4022
|
+
isFavorite,
|
|
4023
|
+
tabs,
|
|
4024
|
+
leverage: imr ? 1 / imr : void 0
|
|
4025
|
+
};
|
|
4281
4026
|
}
|
|
4282
|
-
}
|
|
4283
|
-
return
|
|
4284
|
-
|
|
4027
|
+
}
|
|
4028
|
+
return filter;
|
|
4029
|
+
};
|
|
4030
|
+
const pinToTop = (symbol) => {
|
|
4031
|
+
const index = favorites.findIndex((item) => item.name === symbol.symbol);
|
|
4032
|
+
if (index !== -1) {
|
|
4033
|
+
const element = favorites[index];
|
|
4034
|
+
const list = [...favorites];
|
|
4035
|
+
list.splice(index, 1);
|
|
4036
|
+
list.unshift(element);
|
|
4037
|
+
updateStore("favorites", list);
|
|
4038
|
+
setFavorites(list);
|
|
4039
|
+
}
|
|
4040
|
+
};
|
|
4041
|
+
const getLastSelFavTab = () => {
|
|
4042
|
+
return getStore("lastSelectedFavoriteTab", { ...DefaultTab });
|
|
4043
|
+
};
|
|
4044
|
+
const updateSelectedFavoriteTab = (tab) => {
|
|
4045
|
+
updateStore("lastSelectedFavoriteTab", tab);
|
|
4046
|
+
};
|
|
4047
|
+
const updateTabsSortState = (tabId, sortKey, sortOrder) => {
|
|
4048
|
+
const map = getStore("tabSort", {});
|
|
4049
|
+
map[tabId] = {
|
|
4050
|
+
sortKey,
|
|
4051
|
+
sortOrder
|
|
4285
4052
|
};
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
const
|
|
4290
|
-
|
|
4053
|
+
updateStore("tabSort", map);
|
|
4054
|
+
setTabSort(map);
|
|
4055
|
+
};
|
|
4056
|
+
const markets = getData(type);
|
|
4057
|
+
return [
|
|
4058
|
+
markets || EMPTY_LIST,
|
|
4291
4059
|
{
|
|
4292
|
-
|
|
4060
|
+
favoriteTabs,
|
|
4061
|
+
favorites,
|
|
4062
|
+
recent,
|
|
4063
|
+
tabSort,
|
|
4064
|
+
addToHistory,
|
|
4065
|
+
updateFavorites,
|
|
4066
|
+
updateFavoriteTabs,
|
|
4067
|
+
updateSymbolFavoriteState,
|
|
4068
|
+
pinToTop,
|
|
4069
|
+
getLastSelFavTab,
|
|
4070
|
+
updateSelectedFavoriteTab,
|
|
4071
|
+
updateTabsSortState
|
|
4293
4072
|
}
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4073
|
+
];
|
|
4074
|
+
};
|
|
4075
|
+
function get8hFunding2(est_funding_rate, funding_period) {
|
|
4076
|
+
let funding8h = 0;
|
|
4077
|
+
if (est_funding_rate === void 0 || est_funding_rate === null) {
|
|
4078
|
+
return null;
|
|
4079
|
+
}
|
|
4080
|
+
if (funding_period) {
|
|
4081
|
+
funding8h = new Decimal(est_funding_rate || 0).mul(funding_period).div(8).toNumber();
|
|
4082
|
+
}
|
|
4083
|
+
return funding8h;
|
|
4084
|
+
}
|
|
4085
|
+
function get24hChange2(close, open) {
|
|
4086
|
+
if (close !== void 0 && open !== void 0) {
|
|
4087
|
+
if (open === 0) {
|
|
4088
|
+
return 0;
|
|
4089
|
+
}
|
|
4090
|
+
return new Decimal(close).minus(open).div(open).toNumber();
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
var useMarkPriceStore = create((set, get3) => ({
|
|
4094
|
+
markPrices: {},
|
|
4095
|
+
// orderBook: {},
|
|
4096
|
+
// ask_bid: [],
|
|
4097
|
+
actions: {
|
|
4098
|
+
updateMarkPrice: (markPrice) => {
|
|
4099
|
+
set({
|
|
4100
|
+
markPrices: markPrice
|
|
4101
|
+
});
|
|
4102
|
+
},
|
|
4103
|
+
getMarkPriceBySymbol: (symbol) => {
|
|
4104
|
+
return get3().markPrices[symbol];
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
}));
|
|
4108
|
+
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
4109
|
+
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
4110
|
+
|
|
4111
|
+
// src/orderly/useMarkPricesStream.ts
|
|
4112
|
+
var useMarkPricesStream = () => {
|
|
4113
|
+
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4114
|
+
return { data };
|
|
4115
|
+
};
|
|
4116
|
+
var useIndexPriceStore = create((set) => ({
|
|
4117
|
+
indexPrices: {},
|
|
4118
|
+
actions: {
|
|
4119
|
+
updateIndexPrice: (indexPrice) => {
|
|
4120
|
+
set({
|
|
4121
|
+
indexPrices: indexPrice
|
|
4303
4122
|
});
|
|
4304
|
-
setSortedData(sortedData2);
|
|
4305
4123
|
}
|
|
4306
|
-
}
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4124
|
+
}
|
|
4125
|
+
}));
|
|
4126
|
+
|
|
4127
|
+
// src/orderly/useIndexPricesStream.ts
|
|
4128
|
+
var useIndexPricesStream = () => {
|
|
4129
|
+
const indexPrices = useIndexPriceStore((state) => state.indexPrices);
|
|
4130
|
+
const getIndexPrice = (token) => {
|
|
4131
|
+
if (token === "USDC") {
|
|
4132
|
+
return 1;
|
|
4133
|
+
}
|
|
4134
|
+
return indexPrices[`PERP_${token}_USDC`] ?? 0;
|
|
4135
|
+
};
|
|
4311
4136
|
return {
|
|
4312
|
-
data:
|
|
4313
|
-
|
|
4314
|
-
filterBy,
|
|
4315
|
-
isLoading,
|
|
4316
|
-
error
|
|
4137
|
+
data: indexPrices,
|
|
4138
|
+
getIndexPrice: useMemoizedFn(getIndexPrice)
|
|
4317
4139
|
};
|
|
4318
4140
|
};
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4141
|
+
var generateLeverageLevers = (max2) => {
|
|
4142
|
+
const min2 = 1;
|
|
4143
|
+
const parts = 5;
|
|
4144
|
+
const step = (max2 - min2) / (parts - 1);
|
|
4145
|
+
const result = [];
|
|
4146
|
+
for (let i = 0; i < parts; i++) {
|
|
4147
|
+
result.push(Math.floor(min2 + step * i));
|
|
4324
4148
|
}
|
|
4325
|
-
|
|
4326
|
-
|
|
4149
|
+
return result;
|
|
4150
|
+
};
|
|
4151
|
+
var useLeverage = () => {
|
|
4152
|
+
const { data, mutate: mutate6 } = usePrivateQuery(
|
|
4153
|
+
"/v1/client/info",
|
|
4327
4154
|
{
|
|
4328
4155
|
revalidateOnFocus: false
|
|
4329
4156
|
}
|
|
4330
4157
|
);
|
|
4331
|
-
const [
|
|
4332
|
-
const
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
// return "markprices";
|
|
4345
|
-
// },
|
|
4346
|
-
// onError: (error: any) => {
|
|
4347
|
-
//
|
|
4348
|
-
// },
|
|
4158
|
+
const [update, { isMutating }] = useMutation("/v1/client/leverage");
|
|
4159
|
+
const { data: leverageConfig, isLoading } = useQuery("/v1/public/leverage", {
|
|
4160
|
+
revalidateOnFocus: false,
|
|
4161
|
+
errorRetryCount: 3
|
|
4162
|
+
// formatter: (data) => data,
|
|
4163
|
+
});
|
|
4164
|
+
const updateLeverage = useCallback(
|
|
4165
|
+
async (data2) => {
|
|
4166
|
+
const res = await update(data2);
|
|
4167
|
+
if (res.success) {
|
|
4168
|
+
return mutate6();
|
|
4169
|
+
} else {
|
|
4170
|
+
throw new Error(res.message);
|
|
4349
4171
|
}
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
const { data: markPrice } = useMarkPrice(symbol);
|
|
4357
|
-
const { data: indexPrice } = useIndexPrice(symbol);
|
|
4358
|
-
const { data: openInterest } = useOpenInterest(symbol);
|
|
4359
|
-
const { data: futures } = useFutures();
|
|
4360
|
-
const value = useMemo(() => {
|
|
4361
|
-
if (!info)
|
|
4362
|
-
return null;
|
|
4363
|
-
if (!ticker || ticker.symbol !== symbol)
|
|
4364
|
-
return info;
|
|
4365
|
-
const futureIndex = futures?.findIndex(
|
|
4366
|
-
(item) => item.symbol === symbol
|
|
4367
|
-
);
|
|
4368
|
-
let _oi = openInterest;
|
|
4369
|
-
if (!_oi && futureIndex !== -1 && futures) {
|
|
4370
|
-
_oi = futures[futureIndex].open_interest;
|
|
4371
|
-
}
|
|
4372
|
-
const config = {
|
|
4373
|
-
...info,
|
|
4374
|
-
mark_price: markPrice,
|
|
4375
|
-
index_price: indexPrice,
|
|
4376
|
-
open_interest: _oi
|
|
4377
|
-
};
|
|
4378
|
-
if (ticker.open !== void 0) {
|
|
4379
|
-
config["24h_open"] = ticker.open;
|
|
4380
|
-
}
|
|
4381
|
-
if (ticker.close !== void 0) {
|
|
4382
|
-
config["24h_close"] = ticker.close;
|
|
4383
|
-
}
|
|
4384
|
-
if (ticker.high !== void 0) {
|
|
4385
|
-
config["24h_high"] = ticker.high;
|
|
4386
|
-
}
|
|
4387
|
-
if (ticker.low !== void 0) {
|
|
4388
|
-
config["24h_low"] = ticker.low;
|
|
4389
|
-
}
|
|
4390
|
-
if (ticker.volume !== void 0) {
|
|
4391
|
-
config["24h_volumn"] = ticker.volume;
|
|
4392
|
-
config["24h_volume"] = ticker.volume;
|
|
4172
|
+
},
|
|
4173
|
+
[update, mutate6]
|
|
4174
|
+
);
|
|
4175
|
+
const memoizedCurLeverage = useMemo(() => {
|
|
4176
|
+
if (data?.max_leverage !== void 0) {
|
|
4177
|
+
return Number(data.max_leverage);
|
|
4393
4178
|
}
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4179
|
+
return 1;
|
|
4180
|
+
}, [data?.max_leverage]);
|
|
4181
|
+
const memoizedMaxLeverage = useMemo(() => {
|
|
4182
|
+
if (leverageConfig?.max_futures_leverage !== void 0) {
|
|
4183
|
+
return Number(leverageConfig.max_futures_leverage);
|
|
4397
4184
|
}
|
|
4398
|
-
return
|
|
4399
|
-
}, [
|
|
4400
|
-
|
|
4185
|
+
return 1;
|
|
4186
|
+
}, [leverageConfig?.max_futures_leverage]);
|
|
4187
|
+
const memoizedLeverageLevers = useMemo(() => {
|
|
4188
|
+
return generateLeverageLevers(memoizedMaxLeverage);
|
|
4189
|
+
}, [memoizedMaxLeverage]);
|
|
4190
|
+
return {
|
|
4191
|
+
update: updateLeverage,
|
|
4192
|
+
isLoading: isLoading || isMutating,
|
|
4193
|
+
leverageLevers: memoizedLeverageLevers,
|
|
4194
|
+
curLeverage: memoizedCurLeverage,
|
|
4195
|
+
maxLeverage: memoizedMaxLeverage
|
|
4196
|
+
};
|
|
4401
4197
|
};
|
|
4402
4198
|
|
|
4403
|
-
// src/orderly/
|
|
4404
|
-
var
|
|
4405
|
-
|
|
4406
|
-
return typeof val === "number" && !Number.isNaN(val);
|
|
4407
|
-
};
|
|
4408
|
-
var getPriceKey = (rawPrice, depth, isAsks) => {
|
|
4409
|
-
return new Decimal(rawPrice).div(depth).toDecimalPlaces(0, isAsks ? Decimal.ROUND_CEIL : Decimal.ROUND_FLOOR).mul(depth).toNumber();
|
|
4199
|
+
// src/orderly/useOdosQuote.ts
|
|
4200
|
+
var useOdosQuote = () => {
|
|
4201
|
+
return useMutation(`https://api.odos.xyz/sor/quote/v2`);
|
|
4410
4202
|
};
|
|
4411
|
-
var
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
const result = [];
|
|
4417
|
-
if (typeof depth !== "undefined") {
|
|
4418
|
-
const pricesMap = /* @__PURE__ */ new Map();
|
|
4419
|
-
const len = data.length;
|
|
4420
|
-
for (let i = 0; i < len; i++) {
|
|
4421
|
-
const [rawPrice, quantity] = data[i];
|
|
4422
|
-
if (!isNumber(rawPrice) || !isNumber(quantity)) {
|
|
4423
|
-
continue;
|
|
4424
|
-
}
|
|
4425
|
-
const priceKey = getPriceKey(rawPrice, depth, isAsks);
|
|
4426
|
-
const amtByRaw = new Decimal(rawPrice).mul(quantity).toNumber();
|
|
4427
|
-
if (pricesMap.has(priceKey)) {
|
|
4428
|
-
const item = pricesMap.get(priceKey);
|
|
4429
|
-
const sumQty = new Decimal(item[1]).add(quantity).toNumber();
|
|
4430
|
-
const sumAmtByRaw = new Decimal(item[2] ?? 0).add(amtByRaw).toNumber();
|
|
4431
|
-
pricesMap.set(priceKey, [priceKey, sumQty, sumAmtByRaw]);
|
|
4432
|
-
} else {
|
|
4433
|
-
pricesMap.set(priceKey, [priceKey, quantity, amtByRaw]);
|
|
4434
|
-
}
|
|
4435
|
-
}
|
|
4436
|
-
newData = Array.from(pricesMap.values());
|
|
4437
|
-
}
|
|
4438
|
-
for (let i = 0; i < newData.length; i++) {
|
|
4439
|
-
const [price, quantity, sumAmtByRaw] = newData[i];
|
|
4440
|
-
if (!isNumber(price) || !isNumber(quantity)) {
|
|
4441
|
-
continue;
|
|
4203
|
+
var useTokensInfoStore = create(
|
|
4204
|
+
(set) => ({
|
|
4205
|
+
tokensInfo: [],
|
|
4206
|
+
setTokensInfo(data) {
|
|
4207
|
+
set({ tokensInfo: data });
|
|
4442
4208
|
}
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
}
|
|
4449
|
-
return result;
|
|
4209
|
+
})
|
|
4210
|
+
);
|
|
4211
|
+
var useTokensInfo = () => {
|
|
4212
|
+
const tokensInfo = useTokensInfoStore((state) => state.tokensInfo);
|
|
4213
|
+
return tokensInfo;
|
|
4450
4214
|
};
|
|
4451
|
-
var
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
for (let i = 0; i < asks.length; i++) {
|
|
4471
|
-
if (i === 0) {
|
|
4472
|
-
const quantity = new Decimal(asks[i][1]).add(askQty);
|
|
4473
|
-
asks[i][1] = quantity.toNumber();
|
|
4474
|
-
asks[i][2] = quantity.toNumber();
|
|
4475
|
-
asks[i][3] = quantity.toDecimalPlaces(0, Decimal.ROUND_CEIL).mul(asks[i][0]).toNumber();
|
|
4476
|
-
} else {
|
|
4477
|
-
asks[i][3] = new Decimal(asks[i][0]).mul(asks[i][1]).add(asks[i - 1][3]).toNumber();
|
|
4478
|
-
}
|
|
4479
|
-
}
|
|
4480
|
-
} else {
|
|
4481
|
-
break;
|
|
4482
|
-
}
|
|
4483
|
-
}
|
|
4215
|
+
var useTokenInfo = (token) => {
|
|
4216
|
+
const tokensInfo = useTokensInfo();
|
|
4217
|
+
return useMemo(() => {
|
|
4218
|
+
return tokensInfo?.find((item) => item.token === token);
|
|
4219
|
+
}, [tokensInfo, token]);
|
|
4220
|
+
};
|
|
4221
|
+
|
|
4222
|
+
// src/orderly/useComputedLTV.ts
|
|
4223
|
+
var { LTV, collateralRatio } = account;
|
|
4224
|
+
var useComputedLTV = (options = {}) => {
|
|
4225
|
+
const { input, token } = options;
|
|
4226
|
+
const isUSDC = token?.toUpperCase() === "USDC";
|
|
4227
|
+
const tokensInfo = useTokensInfo();
|
|
4228
|
+
const { usdc, data: holdingList = [] } = useHoldingStream();
|
|
4229
|
+
const { getIndexPrice } = useIndexPricesStream();
|
|
4230
|
+
const { unsettledPnL } = useCollateral();
|
|
4231
|
+
const usdcBalance = useMemo(() => {
|
|
4232
|
+
if (isUSDC && input) {
|
|
4233
|
+
return new Decimal(usdc?.holding ?? 0).add(input).toNumber();
|
|
4484
4234
|
}
|
|
4235
|
+
return usdc?.holding ?? 0;
|
|
4236
|
+
}, [usdc?.holding, input, isUSDC]);
|
|
4237
|
+
const getAdjustedQty = useCallback(
|
|
4238
|
+
(item) => {
|
|
4239
|
+
if (input && item.token === token) {
|
|
4240
|
+
return new Decimal(item?.holding ?? 0).add(input).toNumber();
|
|
4241
|
+
}
|
|
4242
|
+
return item?.holding ?? 0;
|
|
4243
|
+
},
|
|
4244
|
+
[input, token]
|
|
4245
|
+
);
|
|
4246
|
+
const memoizedLTV = useMemo(() => {
|
|
4247
|
+
return LTV({
|
|
4248
|
+
usdcBalance,
|
|
4249
|
+
upnl: unsettledPnL,
|
|
4250
|
+
assets: holdingList.filter((h) => h.token.toUpperCase() !== "USDC").map((item) => {
|
|
4251
|
+
const indexPrice = getIndexPrice(item.token);
|
|
4252
|
+
const findToken = tokensInfo?.find((i) => i.token === item.token);
|
|
4253
|
+
const qty = getAdjustedQty(item);
|
|
4254
|
+
const weight = collateralRatio({
|
|
4255
|
+
baseWeight: findToken?.base_weight ?? 0,
|
|
4256
|
+
discountFactor: findToken?.discount_factor ?? 0,
|
|
4257
|
+
collateralCap: findToken?.user_max_qty ?? qty,
|
|
4258
|
+
collateralQty: qty,
|
|
4259
|
+
indexPrice
|
|
4260
|
+
});
|
|
4261
|
+
return {
|
|
4262
|
+
qty,
|
|
4263
|
+
indexPrice,
|
|
4264
|
+
weight: weight.toNumber()
|
|
4265
|
+
};
|
|
4266
|
+
})
|
|
4267
|
+
});
|
|
4268
|
+
}, [
|
|
4269
|
+
usdcBalance,
|
|
4270
|
+
unsettledPnL,
|
|
4271
|
+
holdingList,
|
|
4272
|
+
tokensInfo,
|
|
4273
|
+
getIndexPrice,
|
|
4274
|
+
getAdjustedQty
|
|
4275
|
+
]);
|
|
4276
|
+
if (new Decimal(usdcBalance).add(new Decimal(unsettledPnL)).gte(zero)) {
|
|
4277
|
+
return 0;
|
|
4485
4278
|
}
|
|
4486
|
-
|
|
4487
|
-
if (padding) {
|
|
4488
|
-
asks = asks.length < level ? paddingFn(level - asks.length).concat(asks) : asks;
|
|
4489
|
-
bids = bids.length < level ? bids.concat(paddingFn(level - bids.length)) : bids;
|
|
4490
|
-
}
|
|
4491
|
-
return {
|
|
4492
|
-
asks,
|
|
4493
|
-
bids
|
|
4494
|
-
};
|
|
4495
|
-
};
|
|
4496
|
-
var ORDERLY_ORDERBOOK_DEPTH_KEY = "orderly_orderbook_depth_key";
|
|
4497
|
-
var INIT_DATA = {
|
|
4498
|
-
asks: [],
|
|
4499
|
-
bids: []
|
|
4279
|
+
return new Decimal(memoizedLTV).mul(100).toDecimalPlaces(2, Decimal.ROUND_DOWN).toNumber();
|
|
4500
4280
|
};
|
|
4501
|
-
var
|
|
4281
|
+
var useFundingRate = (symbol) => {
|
|
4502
4282
|
if (!symbol) {
|
|
4503
4283
|
throw new SDKError("Symbol is required");
|
|
4504
4284
|
}
|
|
4505
|
-
const
|
|
4506
|
-
const
|
|
4507
|
-
const
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
4515
|
-
const config = useSymbolsInfo()[symbol];
|
|
4516
|
-
const [depthObject, setDepthObject] = useLocalStorage(
|
|
4517
|
-
ORDERLY_ORDERBOOK_DEPTH_KEY,
|
|
4518
|
-
{}
|
|
4519
|
-
);
|
|
4520
|
-
const prevMiddlePrice = useRef(0);
|
|
4521
|
-
const tick = config("quote_tick");
|
|
4522
|
-
const depths = useMemo(() => {
|
|
4523
|
-
if (DEFAULT_SYMBOL_DEPTHS2[symbol]) {
|
|
4524
|
-
return DEFAULT_SYMBOL_DEPTHS2[symbol];
|
|
4525
|
-
}
|
|
4526
|
-
if (typeof tick === "undefined") {
|
|
4527
|
-
return [];
|
|
4528
|
-
}
|
|
4529
|
-
try {
|
|
4530
|
-
const base = new Decimal(tick);
|
|
4531
|
-
return [
|
|
4532
|
-
base.toNumber(),
|
|
4533
|
-
base.mul(10).toNumber(),
|
|
4534
|
-
base.mul(100).toNumber(),
|
|
4535
|
-
base.mul(1e3).toNumber()
|
|
4536
|
-
];
|
|
4537
|
-
} catch {
|
|
4285
|
+
const [countDown, setCountDown] = useState("00:00:00");
|
|
4286
|
+
const timerRef = useRef(null);
|
|
4287
|
+
const { data, isLoading } = useQuery(
|
|
4288
|
+
`/v1/public/funding_rate/${symbol}`,
|
|
4289
|
+
{
|
|
4290
|
+
fallbackData: {
|
|
4291
|
+
est_funding_rate: 0,
|
|
4292
|
+
next_funing_time: 0
|
|
4293
|
+
}
|
|
4538
4294
|
}
|
|
4539
|
-
|
|
4540
|
-
}, [symbol, tick]);
|
|
4295
|
+
);
|
|
4541
4296
|
useEffect(() => {
|
|
4542
|
-
if (
|
|
4297
|
+
if (!data || isLoading) {
|
|
4543
4298
|
return;
|
|
4544
4299
|
}
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
[symbol]: Number(DEFAULT_TICK_SIZES2[symbol])
|
|
4549
|
-
}));
|
|
4550
|
-
} else {
|
|
4551
|
-
setDepthObject((prev) => ({
|
|
4552
|
-
...prev,
|
|
4553
|
-
[symbol]: tick
|
|
4554
|
-
}));
|
|
4300
|
+
const { next_funding_time } = data;
|
|
4301
|
+
if (!next_funding_time || next_funding_time <= 0) {
|
|
4302
|
+
return;
|
|
4555
4303
|
}
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
);
|
|
4563
|
-
const ws = useWS();
|
|
4564
|
-
const ticker = useTickerStream(symbol);
|
|
4565
|
-
const eventEmitter = useEventEmitter();
|
|
4566
|
-
useEffect(() => {
|
|
4567
|
-
let needRequestFullOrderbook = true;
|
|
4568
|
-
setIsLoading(true);
|
|
4569
|
-
let fullOrderBookUpdateSub;
|
|
4570
|
-
const orderBookUpdateSub = ws.subscribe(
|
|
4571
|
-
{
|
|
4572
|
-
event: "subscribe",
|
|
4573
|
-
topic: `${symbol}@orderbookupdate`
|
|
4574
|
-
},
|
|
4575
|
-
{
|
|
4576
|
-
formatter: (message) => message,
|
|
4577
|
-
onMessage: (message) => {
|
|
4578
|
-
const { data: wsData, ts } = message;
|
|
4579
|
-
const { symbol: symbol2, asks, bids, prevTs } = wsData;
|
|
4580
|
-
if (symbolRef.current !== symbol2) {
|
|
4581
|
-
orderBookUpdateSub?.();
|
|
4582
|
-
return;
|
|
4583
|
-
}
|
|
4584
|
-
orderbook_service_default.updateOrderbook(
|
|
4585
|
-
symbol2,
|
|
4586
|
-
{ asks, bids, ts, prevTs },
|
|
4587
|
-
() => {
|
|
4588
|
-
needRequestFullOrderbook = true;
|
|
4589
|
-
}
|
|
4590
|
-
);
|
|
4591
|
-
const data2 = orderbook_service_default.getRawOrderbook(symbol2);
|
|
4592
|
-
setData({ bids: data2.bids, asks: data2.asks });
|
|
4304
|
+
timerRef.current = setInterval(() => {
|
|
4305
|
+
const diff = new Date(next_funding_time).getTime() - getTimestamp();
|
|
4306
|
+
if (diff <= 0) {
|
|
4307
|
+
setCountDown("00:00:00");
|
|
4308
|
+
if (timerRef.current) {
|
|
4309
|
+
clearInterval(timerRef.current);
|
|
4593
4310
|
}
|
|
4311
|
+
return;
|
|
4312
|
+
}
|
|
4313
|
+
const result = timeConvertString(diff);
|
|
4314
|
+
if (result.length === 3) {
|
|
4315
|
+
setCountDown(
|
|
4316
|
+
`${result[0].toString().padStart(2, "0")}:${result[1].toString().padStart(2, "0")}:${result[2].toString().padStart(2, "0")}`
|
|
4317
|
+
);
|
|
4318
|
+
}
|
|
4319
|
+
}, 1e3);
|
|
4320
|
+
return () => {
|
|
4321
|
+
if (timerRef.current) {
|
|
4322
|
+
clearInterval(timerRef.current);
|
|
4594
4323
|
}
|
|
4324
|
+
};
|
|
4325
|
+
}, [data, isLoading]);
|
|
4326
|
+
const est_funding_rate = useMemo(() => {
|
|
4327
|
+
if (!data) {
|
|
4328
|
+
return;
|
|
4329
|
+
}
|
|
4330
|
+
const { next_funding_time, est_funding_rate: est_funding_rate2 = 0 } = data;
|
|
4331
|
+
if (getTimestamp() > next_funding_time) {
|
|
4332
|
+
return null;
|
|
4333
|
+
}
|
|
4334
|
+
return new Decimal(Number(est_funding_rate2) * 100).toFixed(
|
|
4335
|
+
4,
|
|
4336
|
+
Decimal.ROUND_DOWN
|
|
4595
4337
|
);
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4338
|
+
}, [data]);
|
|
4339
|
+
return {
|
|
4340
|
+
...data,
|
|
4341
|
+
est_funding_rate,
|
|
4342
|
+
countDown
|
|
4343
|
+
};
|
|
4344
|
+
};
|
|
4345
|
+
var useFundingDetails = (symbol) => {
|
|
4346
|
+
if (!symbol) {
|
|
4347
|
+
throw new SDKError("symbol is required");
|
|
4348
|
+
}
|
|
4349
|
+
return useQuery(`/v1/public/info/${symbol}`, {
|
|
4350
|
+
errorRetryCount: 3,
|
|
4351
|
+
revalidateOnFocus: false
|
|
4352
|
+
});
|
|
4353
|
+
};
|
|
4354
|
+
var calculatePositiveRate = (periodData, period) => {
|
|
4355
|
+
if (!periodData || !period) {
|
|
4356
|
+
return 0;
|
|
4357
|
+
}
|
|
4358
|
+
const daysMap = {
|
|
4359
|
+
"1d": 1,
|
|
4360
|
+
"3d": 3,
|
|
4361
|
+
"7d": 7,
|
|
4362
|
+
"14d": 14,
|
|
4363
|
+
"30d": 30,
|
|
4364
|
+
"90d": 90
|
|
4365
|
+
};
|
|
4366
|
+
const totalTimes = daysMap[period] * 3;
|
|
4367
|
+
return periodData.positive / totalTimes;
|
|
4368
|
+
};
|
|
4369
|
+
var useFundingRateHistory = () => {
|
|
4370
|
+
const { data: historyData, isLoading } = useQuery(
|
|
4371
|
+
"/v1/public/market_info/funding_history"
|
|
4372
|
+
);
|
|
4373
|
+
const getPositiveRates = useCallback(
|
|
4374
|
+
(data, period) => {
|
|
4375
|
+
if (!data?.length) {
|
|
4376
|
+
return {};
|
|
4377
|
+
}
|
|
4378
|
+
return data.reduce(
|
|
4379
|
+
(acc, item) => {
|
|
4380
|
+
acc[item.symbol] = calculatePositiveRate(
|
|
4381
|
+
item.funding[period],
|
|
4382
|
+
period
|
|
4383
|
+
);
|
|
4384
|
+
return acc;
|
|
4606
4385
|
},
|
|
4607
|
-
{
|
|
4608
|
-
formatter: (message) => message,
|
|
4609
|
-
onMessage: (message) => {
|
|
4610
|
-
const { symbol: symbol2, asks, bids, ts } = message.data;
|
|
4611
|
-
if (symbolRef.current !== symbol2) {
|
|
4612
|
-
return;
|
|
4613
|
-
}
|
|
4614
|
-
orderbook_service_default.setFullOrderbook(symbol2, { asks, bids, ts });
|
|
4615
|
-
const data2 = orderbook_service_default.getRawOrderbook(symbol2);
|
|
4616
|
-
setData({ bids: data2.bids, asks: data2.asks });
|
|
4617
|
-
setIsLoading(false);
|
|
4618
|
-
}
|
|
4619
|
-
}
|
|
4386
|
+
{}
|
|
4620
4387
|
);
|
|
4621
|
-
needRequestFullOrderbook = false;
|
|
4622
|
-
}
|
|
4623
|
-
return () => {
|
|
4624
|
-
orderBookUpdateSub?.();
|
|
4625
|
-
fullOrderBookUpdateSub?.();
|
|
4626
|
-
orderbook_service_default.resetOrderBook(symbol);
|
|
4627
|
-
setData(INIT_DATA);
|
|
4628
|
-
};
|
|
4629
|
-
}, [symbol]);
|
|
4630
|
-
const { data: markPrice } = useMarkPrice(symbol);
|
|
4631
|
-
const onItemClick = useCallback((item) => {
|
|
4632
|
-
eventEmitter.emit("orderbook:item:click", item);
|
|
4633
|
-
}, []);
|
|
4634
|
-
const reducedData = reduceOrderbook(depthObject[symbol], level, padding, {
|
|
4635
|
-
asks: data.asks,
|
|
4636
|
-
bids: data.bids
|
|
4637
|
-
});
|
|
4638
|
-
useEffect(() => {
|
|
4639
|
-
eventEmitter.emit("orderbook:update", reducedData);
|
|
4640
|
-
}, [reducedData]);
|
|
4641
|
-
const middlePrice = useMemo(() => {
|
|
4642
|
-
let asksFrist = 0;
|
|
4643
|
-
let bidsFirst = 0;
|
|
4644
|
-
if (data.asks.length > 0) {
|
|
4645
|
-
asksFrist = reducedData.asks?.[reducedData.asks.length - 1]?.[0];
|
|
4646
|
-
}
|
|
4647
|
-
if (data.bids.length > 0) {
|
|
4648
|
-
bidsFirst = data.bids[0][0];
|
|
4649
|
-
}
|
|
4650
|
-
if (!isNumber(asksFrist) || !isNumber(bidsFirst) || !ticker) {
|
|
4651
|
-
return 0;
|
|
4652
|
-
}
|
|
4653
|
-
return [asksFrist, bidsFirst, ticker["24h_close"]].sort()[1];
|
|
4654
|
-
}, [ticker?.["24h_close"], data]);
|
|
4655
|
-
useEffect(() => {
|
|
4656
|
-
prevMiddlePrice.current = middlePrice;
|
|
4657
|
-
}, [middlePrice]);
|
|
4658
|
-
return [
|
|
4659
|
-
{
|
|
4660
|
-
asks: reducedData.asks.slice(-level),
|
|
4661
|
-
bids: reducedData.bids.slice(0, level),
|
|
4662
|
-
markPrice,
|
|
4663
|
-
middlePrice: [prevMiddlePrice.current, middlePrice]
|
|
4664
4388
|
},
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4389
|
+
[]
|
|
4390
|
+
);
|
|
4391
|
+
return useMemo(() => {
|
|
4392
|
+
return {
|
|
4393
|
+
data: historyData ?? EMPTY_LIST,
|
|
4669
4394
|
isLoading,
|
|
4670
|
-
|
|
4671
|
-
}
|
|
4672
|
-
];
|
|
4395
|
+
getPositiveRates
|
|
4396
|
+
};
|
|
4397
|
+
}, [historyData, isLoading, getPositiveRates]);
|
|
4673
4398
|
};
|
|
4674
|
-
var
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4399
|
+
var useApiStatusStore = create()(
|
|
4400
|
+
immer((set) => ({
|
|
4401
|
+
apis: {
|
|
4402
|
+
positions: {
|
|
4403
|
+
loading: false
|
|
4404
|
+
}
|
|
4405
|
+
},
|
|
4406
|
+
actions: {
|
|
4407
|
+
updateStatus: (key, status) => {
|
|
4408
|
+
set((state) => {
|
|
4409
|
+
state.apis[key] = status;
|
|
4410
|
+
});
|
|
4411
|
+
},
|
|
4412
|
+
updateApiLoading: (key, loading) => {
|
|
4413
|
+
set((state) => {
|
|
4414
|
+
state.apis[key].loading = loading;
|
|
4415
|
+
});
|
|
4416
|
+
},
|
|
4417
|
+
updateApiError: (key, error) => {
|
|
4418
|
+
set((state) => {
|
|
4419
|
+
state.apis[key] = {
|
|
4420
|
+
loading: false,
|
|
4421
|
+
error
|
|
4422
|
+
};
|
|
4423
|
+
});
|
|
4424
|
+
}
|
|
4425
|
+
}
|
|
4426
|
+
}))
|
|
4427
|
+
);
|
|
4428
|
+
var useApiStatusActions = () => useApiStatusStore((state) => state.actions);
|
|
4429
|
+
|
|
4430
|
+
// src/orderly/calculator/baseCalculator.ts
|
|
4431
|
+
var BaseCalculator = class {
|
|
4432
|
+
cache(data) {
|
|
4433
|
+
this._cache = data;
|
|
4434
|
+
}
|
|
4679
4435
|
};
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4436
|
+
|
|
4437
|
+
// src/orderly/calculator/markPrice.ts
|
|
4438
|
+
var MarketCalculatorName = "markPriceCalculator";
|
|
4439
|
+
var MarkPriceCalculator = class extends BaseCalculator {
|
|
4440
|
+
constructor() {
|
|
4441
|
+
super(...arguments);
|
|
4442
|
+
this.name = MarketCalculatorName;
|
|
4443
|
+
}
|
|
4444
|
+
calc(scope, data, ctx) {
|
|
4445
|
+
return data;
|
|
4446
|
+
}
|
|
4447
|
+
update(data, scope) {
|
|
4448
|
+
useMarkPriceStore.getState().actions.updateMarkPrice(data);
|
|
4449
|
+
}
|
|
4683
4450
|
};
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4451
|
+
|
|
4452
|
+
// src/orderly/calculator/calculatorContext.ts
|
|
4453
|
+
var CalculatorContext = class _CalculatorContext {
|
|
4454
|
+
static get instance() {
|
|
4455
|
+
return this._instance;
|
|
4456
|
+
}
|
|
4457
|
+
static create(scope, data) {
|
|
4458
|
+
if (!this._instance) {
|
|
4459
|
+
this._instance = new _CalculatorContext(scope, data);
|
|
4460
|
+
}
|
|
4461
|
+
return this._instance.update(scope, data);
|
|
4462
|
+
}
|
|
4463
|
+
constructor(scope, data) {
|
|
4464
|
+
this.setCtxData();
|
|
4465
|
+
this.output = {
|
|
4466
|
+
// rows: positions,
|
|
4467
|
+
};
|
|
4468
|
+
}
|
|
4469
|
+
update(scope, data) {
|
|
4470
|
+
this.setCtxData();
|
|
4471
|
+
this.markPrices = scope === "markPrice" /* MARK_PRICE */ ? data : this.output[MarketCalculatorName];
|
|
4472
|
+
this.portfolio = this.output["portfolio"] || useAppStore.getState().portfolio;
|
|
4473
|
+
return this;
|
|
4474
|
+
}
|
|
4475
|
+
setCtxData() {
|
|
4476
|
+
this.accountInfo = useAppStore.getState().accountInfo;
|
|
4477
|
+
this.symbolsInfo = useAppStore.getState().symbolsInfo;
|
|
4478
|
+
this.fundingRates = useAppStore.getState().fundingRates;
|
|
4479
|
+
this.tokensInfo = useTokensInfoStore.getState().tokensInfo;
|
|
4480
|
+
}
|
|
4481
|
+
get(fn) {
|
|
4482
|
+
return fn(this.output);
|
|
4483
|
+
}
|
|
4484
|
+
getCacheValue(name, fallback) {
|
|
4485
|
+
return this.output[name] || fallback();
|
|
4486
|
+
}
|
|
4487
|
+
clearCache() {
|
|
4488
|
+
this.output = {};
|
|
4489
|
+
this.accountInfo = void 0;
|
|
4490
|
+
this.portfolio = void 0;
|
|
4491
|
+
}
|
|
4492
|
+
deleteByName(name) {
|
|
4493
|
+
delete this.output[name];
|
|
4494
|
+
}
|
|
4495
|
+
// get positions(): API.PositionTPSLExt[] {
|
|
4496
|
+
// if (this.output.positionCalculator) return this.output.positionCalculator;
|
|
4497
|
+
// return usePositionStore.getState().positions;
|
|
4498
|
+
// }
|
|
4499
|
+
get isReady() {
|
|
4500
|
+
return !!this.accountInfo;
|
|
4501
|
+
}
|
|
4502
|
+
saveOutput(name, data) {
|
|
4503
|
+
this.output[name] = data;
|
|
4504
|
+
}
|
|
4505
|
+
outputToValue() {
|
|
4506
|
+
return this.output;
|
|
4507
|
+
}
|
|
4687
4508
|
};
|
|
4688
4509
|
|
|
4689
|
-
// src/orderly/
|
|
4690
|
-
var
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4510
|
+
// src/orderly/calculator/calculatorService.ts
|
|
4511
|
+
var CalculatorService = class {
|
|
4512
|
+
constructor(scheduler, calculators) {
|
|
4513
|
+
this.scheduler = scheduler;
|
|
4514
|
+
this.pendingCalc = [];
|
|
4515
|
+
this.calcQueue = [];
|
|
4516
|
+
/**
|
|
4517
|
+
* Reference count for each calculator, used to determine if a calculator is still in use.
|
|
4518
|
+
*/
|
|
4519
|
+
this.referenceCount = /* @__PURE__ */ new Map();
|
|
4520
|
+
this.isPaused = false;
|
|
4521
|
+
this.calculators = new Map(calculators);
|
|
4522
|
+
}
|
|
4523
|
+
register(scope, calculator) {
|
|
4524
|
+
const ref_count_name = `${scope}_${calculator.name}`;
|
|
4525
|
+
const count = this.referenceCount.get(ref_count_name);
|
|
4526
|
+
if (typeof count !== "undefined" && count > 0) {
|
|
4527
|
+
this.referenceCount.set(ref_count_name, count + 1);
|
|
4528
|
+
return;
|
|
4529
|
+
}
|
|
4530
|
+
const calculators = this.calculators.get(scope);
|
|
4531
|
+
if (Array.isArray(calculators)) {
|
|
4532
|
+
calculators.push(calculator);
|
|
4710
4533
|
} else {
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4534
|
+
this.calculators.set(scope, [calculator]);
|
|
4535
|
+
}
|
|
4536
|
+
this.referenceCount.set(ref_count_name, 1);
|
|
4537
|
+
}
|
|
4538
|
+
unregister(scope, calculator) {
|
|
4539
|
+
const ref_count_name = `${scope}_${calculator.name}`;
|
|
4540
|
+
const count = this.referenceCount.get(ref_count_name);
|
|
4541
|
+
if (typeof count !== "undefined" && count > 1) {
|
|
4542
|
+
this.referenceCount.set(ref_count_name, count - 1);
|
|
4543
|
+
return;
|
|
4544
|
+
}
|
|
4545
|
+
const calculators = this.calculators.get(scope);
|
|
4546
|
+
if (Array.isArray(calculators)) {
|
|
4547
|
+
const index = calculators.findIndex((c) => c.name === calculator.name);
|
|
4548
|
+
if (index > -1) {
|
|
4549
|
+
calculators[index].destroy?.();
|
|
4550
|
+
calculators.splice(index, 1);
|
|
4551
|
+
}
|
|
4720
4552
|
}
|
|
4553
|
+
this.referenceCount.delete(ref_count_name);
|
|
4721
4554
|
}
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
const getFavorites = useMemo(() => {
|
|
4726
|
-
const curData = getStore("favorites", []);
|
|
4727
|
-
const tabs = getFavoriteTabs;
|
|
4728
|
-
const result = [];
|
|
4729
|
-
const len = curData.length;
|
|
4730
|
-
for (let index = 0; index < len; index++) {
|
|
4731
|
-
const favData = curData[index];
|
|
4732
|
-
const favTabs = favData.tabs.filter(
|
|
4733
|
-
(tab) => tabs.findIndex((item) => tab.id === item.id) !== -1
|
|
4734
|
-
);
|
|
4735
|
-
if (favTabs.length) {
|
|
4736
|
-
result.push({ ...favData, tabs: favTabs });
|
|
4737
|
-
}
|
|
4555
|
+
async calc(scope, data, options) {
|
|
4556
|
+
if (scope !== "position" /* POSITION */) {
|
|
4557
|
+
if (!options?.skipWhenOnPause) ;
|
|
4738
4558
|
}
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
}, [configStore]);
|
|
4742
|
-
const [favoriteTabs, setFavoriteTabs] = useState(getFavoriteTabs);
|
|
4743
|
-
const [favorites, setFavorites] = useState(getFavorites);
|
|
4744
|
-
const [recent, setRecent] = useState(
|
|
4745
|
-
getStore("recent", []).filter((e) => e)
|
|
4746
|
-
);
|
|
4747
|
-
const [tabSort, setTabSort] = useState(
|
|
4748
|
-
getStore("tabSort", {})
|
|
4749
|
-
);
|
|
4750
|
-
const updateFavoriteTabs = (tab, operator) => {
|
|
4751
|
-
const saveTabs = (tabs2) => {
|
|
4752
|
-
setFavoriteTabs(tabs2);
|
|
4753
|
-
updateStore("favoriteTabs", tabs2);
|
|
4754
|
-
};
|
|
4755
|
-
if (Array.isArray(tab)) {
|
|
4756
|
-
saveTabs(tab);
|
|
4559
|
+
const ctx = CalculatorContext.create(scope, data);
|
|
4560
|
+
if (!ctx.isReady && options?.skipPending) {
|
|
4757
4561
|
return;
|
|
4758
4562
|
}
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4563
|
+
if (options?.skipWhenOnPause && !this.windowIsVisible)
|
|
4564
|
+
return;
|
|
4565
|
+
this.calcQueue.push({ scope, data, options });
|
|
4566
|
+
await this.handleCalcQueue(ctx);
|
|
4567
|
+
this.ctx = ctx;
|
|
4568
|
+
}
|
|
4569
|
+
// private async handlePendingCalc() {
|
|
4570
|
+
// // console.log("[handlePendingCalc]:", this.pendingCalc);
|
|
4571
|
+
// if (this.pendingCalc.length === 0) return;
|
|
4572
|
+
// this.calcQueue = [...this.pendingCalc, ...this.calcQueue];
|
|
4573
|
+
// this.pendingCalc = [];
|
|
4574
|
+
// }
|
|
4575
|
+
async handleCalcQueue(context) {
|
|
4576
|
+
const first = this.calcQueue.shift();
|
|
4577
|
+
if (first) {
|
|
4578
|
+
const { scope, data, options } = first;
|
|
4579
|
+
const ctx = context || CalculatorContext.create(scope, data);
|
|
4580
|
+
const calculators = this.calculators.get(scope);
|
|
4581
|
+
if (Array.isArray(calculators) && calculators.length) {
|
|
4582
|
+
try {
|
|
4583
|
+
await this.scheduler.calc(scope, calculators, data, ctx);
|
|
4584
|
+
} catch (e) {
|
|
4585
|
+
}
|
|
4586
|
+
if (!options?.skipUpdate) {
|
|
4587
|
+
this.scheduler.update(scope, calculators, ctx.outputToValue());
|
|
4588
|
+
}
|
|
4766
4589
|
}
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
tabs.splice(index, 1);
|
|
4590
|
+
if (this.calcQueue.length) {
|
|
4591
|
+
this.handleCalcQueue(ctx);
|
|
4770
4592
|
}
|
|
4771
4593
|
}
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
const index = curData.findIndex((item) => item.name == symbol.symbol);
|
|
4781
|
-
if (index !== -1) {
|
|
4782
|
-
curData.splice(index, 1);
|
|
4594
|
+
}
|
|
4595
|
+
stop() {
|
|
4596
|
+
this.calcQueue = [];
|
|
4597
|
+
this.ctx?.clearCache();
|
|
4598
|
+
}
|
|
4599
|
+
get windowIsVisible() {
|
|
4600
|
+
if (typeof document === "undefined") {
|
|
4601
|
+
return true;
|
|
4783
4602
|
}
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4603
|
+
return document.visibilityState === "visible";
|
|
4604
|
+
}
|
|
4605
|
+
};
|
|
4606
|
+
var CalculatorServiceID = "CalculatorService";
|
|
4607
|
+
|
|
4608
|
+
// src/orderly/calculator/shardedScheduler.ts
|
|
4609
|
+
var requestIdleCallbackPolyfill = (callback, options) => {
|
|
4610
|
+
const startTime = Date.now();
|
|
4611
|
+
return setTimeout(() => {
|
|
4612
|
+
callback({
|
|
4613
|
+
didTimeout: false,
|
|
4614
|
+
timeRemaining: () => Math.max(0, 50 - (Date.now() - startTime))
|
|
4615
|
+
});
|
|
4616
|
+
}, 1);
|
|
4617
|
+
};
|
|
4618
|
+
var cancelIdleCallbackPolyfill = (id) => {
|
|
4619
|
+
clearTimeout(id);
|
|
4620
|
+
};
|
|
4621
|
+
var safeRequestIdleCallback = typeof window !== "undefined" && window.requestIdleCallback ? window.requestIdleCallback.bind(window) : requestIdleCallbackPolyfill;
|
|
4622
|
+
typeof window !== "undefined" && window.cancelIdleCallback ? window.cancelIdleCallback.bind(window) : cancelIdleCallbackPolyfill;
|
|
4623
|
+
var ShardingScheduler = class {
|
|
4624
|
+
// run(calculators: Calculator[]) {}
|
|
4625
|
+
calc(scope, calculators, data, ctx) {
|
|
4626
|
+
return new Promise((resolve, reject) => {
|
|
4627
|
+
try {
|
|
4628
|
+
this.computation(
|
|
4629
|
+
calculators,
|
|
4630
|
+
(shard) => {
|
|
4631
|
+
const results = [];
|
|
4632
|
+
for (let index = 0; index < shard.length; index++) {
|
|
4633
|
+
const calculator = shard[index];
|
|
4634
|
+
const result = calculator.calc(scope, data, ctx);
|
|
4635
|
+
if (result) {
|
|
4636
|
+
ctx.saveOutput(calculator.name, result);
|
|
4637
|
+
results.push(result);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
return results;
|
|
4641
|
+
},
|
|
4642
|
+
(results) => {
|
|
4643
|
+
resolve(results);
|
|
4644
|
+
}
|
|
4645
|
+
);
|
|
4646
|
+
} catch (error) {
|
|
4647
|
+
reject(error);
|
|
4800
4648
|
}
|
|
4801
|
-
}
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4649
|
+
});
|
|
4650
|
+
}
|
|
4651
|
+
update(scope, calculators, data) {
|
|
4652
|
+
for (let index = 0; index < calculators.length; index++) {
|
|
4653
|
+
const calculator = calculators[index];
|
|
4654
|
+
const item = data[calculator.name];
|
|
4655
|
+
if (!!item) {
|
|
4656
|
+
calculator.update(item, scope);
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
return Promise.resolve();
|
|
4660
|
+
}
|
|
4661
|
+
computation(data, processor, onComplete) {
|
|
4662
|
+
let index = 0;
|
|
4663
|
+
const results = [];
|
|
4664
|
+
const estimatedShardSize = Math.min(data.length, 2);
|
|
4665
|
+
function processNextShard(deadline) {
|
|
4666
|
+
let shardSize = estimatedShardSize;
|
|
4667
|
+
while (index + shardSize <= data.length && deadline.timeRemaining() > 0) {
|
|
4668
|
+
const shard = data.slice(index, index + shardSize);
|
|
4669
|
+
const result = processor(shard);
|
|
4670
|
+
results.push(result);
|
|
4671
|
+
index += shardSize;
|
|
4672
|
+
if (deadline.timeRemaining() < 1) {
|
|
4673
|
+
shardSize = Math.max(1, Math.floor(shardSize / 2));
|
|
4806
4674
|
} else {
|
|
4807
|
-
|
|
4675
|
+
shardSize = Math.min(data.length - index, shardSize * 2);
|
|
4808
4676
|
}
|
|
4677
|
+
}
|
|
4678
|
+
if (index < data.length) {
|
|
4679
|
+
safeRequestIdleCallback(processNextShard, {
|
|
4680
|
+
timeout: 1e3
|
|
4681
|
+
});
|
|
4809
4682
|
} else {
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4683
|
+
onComplete(results.flat());
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
safeRequestIdleCallback(processNextShard, {
|
|
4687
|
+
timeout: 1e3
|
|
4688
|
+
});
|
|
4689
|
+
}
|
|
4690
|
+
};
|
|
4691
|
+
var POSITION_EMPTY = {
|
|
4692
|
+
rows: null,
|
|
4693
|
+
margin_ratio: 0,
|
|
4694
|
+
initial_margin_ratio: 0,
|
|
4695
|
+
maintenance_margin_ratio: 0,
|
|
4696
|
+
open_margin_ratio: 0,
|
|
4697
|
+
current_margin_ratio_with_orders: 0,
|
|
4698
|
+
initial_margin_ratio_with_orders: 0,
|
|
4699
|
+
maintenance_margin_ratio_with_orders: 0,
|
|
4700
|
+
total_collateral_value: 0,
|
|
4701
|
+
free_collateral: 0,
|
|
4702
|
+
total_pnl_24_h: 0,
|
|
4703
|
+
unrealPnL: 0,
|
|
4704
|
+
total_unreal_pnl: 0,
|
|
4705
|
+
unsettledPnL: 0,
|
|
4706
|
+
total_unsettled_pnl: 0,
|
|
4707
|
+
notional: 0,
|
|
4708
|
+
unrealPnlROI: 0
|
|
4709
|
+
};
|
|
4710
|
+
var usePositionStore = create()(
|
|
4711
|
+
immer((set) => ({
|
|
4712
|
+
positions: {
|
|
4713
|
+
all: POSITION_EMPTY
|
|
4714
|
+
},
|
|
4715
|
+
actions: {
|
|
4716
|
+
setPositions: (key, positions3) => {
|
|
4717
|
+
set((state) => {
|
|
4718
|
+
state.positions[key] = positions3;
|
|
4719
|
+
});
|
|
4720
|
+
},
|
|
4721
|
+
closePosition: (symbol) => {
|
|
4722
|
+
set((state) => {
|
|
4723
|
+
delete state.positions[symbol];
|
|
4724
|
+
});
|
|
4725
|
+
},
|
|
4726
|
+
clearAll: () => {
|
|
4727
|
+
set((state) => {
|
|
4728
|
+
state.positions = {
|
|
4729
|
+
all: POSITION_EMPTY
|
|
4730
|
+
};
|
|
4731
|
+
});
|
|
4822
4732
|
}
|
|
4823
4733
|
}
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4734
|
+
}))
|
|
4735
|
+
);
|
|
4736
|
+
var usePositions = (symbol = "all") => usePositionStore((state) => (state.positions[symbol] ?? POSITION_EMPTY).rows);
|
|
4737
|
+
var usePositionActions = () => usePositionStore((state) => state.actions);
|
|
4738
|
+
|
|
4739
|
+
// src/orderly/calculator/positions.ts
|
|
4740
|
+
var NAME_PREFIX = "positionCalculator";
|
|
4741
|
+
var AllPositions = "all";
|
|
4742
|
+
var PositionCalculator = class extends BaseCalculator {
|
|
4743
|
+
// private id: string;
|
|
4744
|
+
constructor(symbol = AllPositions) {
|
|
4745
|
+
super();
|
|
4746
|
+
this.name = `${NAME_PREFIX}_${symbol}`;
|
|
4747
|
+
this.symbol = symbol;
|
|
4748
|
+
}
|
|
4749
|
+
calc(scope, data, ctx) {
|
|
4750
|
+
if (scope === "markPrice" /* MARK_PRICE */) {
|
|
4751
|
+
return this.calcByMarkPrice(data, ctx);
|
|
4752
|
+
}
|
|
4753
|
+
if (scope === "indexPrice" /* INDEX_PRICE */) {
|
|
4754
|
+
return this.calcByIndexPrice(data, ctx);
|
|
4755
|
+
}
|
|
4756
|
+
if (scope === "position" /* POSITION */) {
|
|
4757
|
+
return this.calcByPosition(
|
|
4758
|
+
this.preprocess(data),
|
|
4759
|
+
ctx
|
|
4760
|
+
);
|
|
4761
|
+
}
|
|
4762
|
+
return data;
|
|
4763
|
+
}
|
|
4764
|
+
update(data, scope) {
|
|
4765
|
+
if (!data || !Array.isArray(data.rows))
|
|
4766
|
+
return;
|
|
4767
|
+
usePositionStore.getState().actions.setPositions(this.symbol, data);
|
|
4768
|
+
if (Array.isArray(data.rows) && useApiStatusStore.getState().apis.positions.loading) {
|
|
4769
|
+
useApiStatusStore.getState().actions.updateApiLoading("positions", false);
|
|
4770
|
+
}
|
|
4771
|
+
}
|
|
4772
|
+
calcByMarkPrice(markPrice, ctx) {
|
|
4773
|
+
let positions3 = this.getPosition(markPrice, ctx);
|
|
4774
|
+
useAppStore.getState().fundingRates;
|
|
4775
|
+
if (!positions3 || !Array.isArray(positions3.rows) || !positions3.rows.length)
|
|
4776
|
+
return positions3;
|
|
4777
|
+
positions3 = {
|
|
4778
|
+
...positions3,
|
|
4779
|
+
rows: positions3.rows.map((item) => {
|
|
4780
|
+
return {
|
|
4781
|
+
...item,
|
|
4782
|
+
mark_price: markPrice[item.symbol] || item.mark_price
|
|
4783
|
+
};
|
|
4784
|
+
})
|
|
4785
|
+
};
|
|
4786
|
+
return this.format(positions3, ctx);
|
|
4787
|
+
}
|
|
4788
|
+
calcByIndexPrice(indexPrice, ctx) {
|
|
4789
|
+
let positions3 = this.getPosition(indexPrice, ctx);
|
|
4790
|
+
if (!positions3) {
|
|
4791
|
+
return positions3;
|
|
4792
|
+
}
|
|
4793
|
+
if (!Array.isArray(positions3.rows) || !positions3.rows.length)
|
|
4794
|
+
return positions3;
|
|
4795
|
+
positions3 = {
|
|
4796
|
+
...positions3,
|
|
4797
|
+
rows: positions3.rows.map((item) => ({
|
|
4798
|
+
...item,
|
|
4799
|
+
index_price: indexPrice[item.symbol] || item.index_price || item.mark_price
|
|
4800
|
+
}))
|
|
4801
|
+
};
|
|
4802
|
+
return this.format(positions3, ctx);
|
|
4803
|
+
}
|
|
4804
|
+
calcByPosition(positions3, ctx) {
|
|
4805
|
+
if (positions3.rows.length === 0)
|
|
4806
|
+
return positions3;
|
|
4807
|
+
return this.format(positions3, ctx);
|
|
4808
|
+
}
|
|
4809
|
+
format(data, ctx) {
|
|
4810
|
+
const { accountInfo, symbolsInfo, fundingRates, portfolio } = ctx;
|
|
4811
|
+
if (!accountInfo || !fundingRates || !symbolsInfo) {
|
|
4812
|
+
return data;
|
|
4813
|
+
}
|
|
4814
|
+
let unrealPnL_total = zero, unrealPnL_total_index = zero, notional_total = zero, unsettlementPnL_total = zero;
|
|
4815
|
+
let rows = data.rows.map((item) => {
|
|
4830
4816
|
const info = symbolsInfo[item.symbol];
|
|
4831
|
-
const
|
|
4832
|
-
const
|
|
4833
|
-
const
|
|
4834
|
-
|
|
4817
|
+
const sum_unitary_funding = fundingRates?.[item.symbol]?.["sum_unitary_funding"] ?? 0;
|
|
4818
|
+
const notional = positions.notional(item.position_qty, item.mark_price);
|
|
4819
|
+
const unrealPnl = positions.unrealizedPnL({
|
|
4820
|
+
qty: item.position_qty,
|
|
4821
|
+
openPrice: item?.average_open_price,
|
|
4822
|
+
// markPrice: unRealizedPrice,
|
|
4823
|
+
markPrice: item.mark_price
|
|
4824
|
+
});
|
|
4825
|
+
let unrealPnl_index = 0, unrealPnlROI_index = 0;
|
|
4826
|
+
const maxLeverage = item.leverage || 1;
|
|
4827
|
+
const imr = account.IMR({
|
|
4828
|
+
maxLeverage,
|
|
4829
|
+
baseIMR: info?.["base_imr"],
|
|
4830
|
+
IMR_Factor: accountInfo.imr_factor[item.symbol],
|
|
4831
|
+
positionNotional: notional,
|
|
4832
|
+
ordersNotional: 0,
|
|
4833
|
+
IMR_factor_power: 4 / 5
|
|
4834
|
+
});
|
|
4835
|
+
const unrealPnlROI = positions.unrealizedPnLROI({
|
|
4836
|
+
positionQty: item.position_qty,
|
|
4837
|
+
openPrice: item.average_open_price,
|
|
4838
|
+
IMR: imr,
|
|
4839
|
+
unrealizedPnL: unrealPnl
|
|
4840
|
+
});
|
|
4841
|
+
if (item.index_price) {
|
|
4842
|
+
unrealPnl_index = positions.unrealizedPnL({
|
|
4843
|
+
qty: item.position_qty,
|
|
4844
|
+
openPrice: item?.average_open_price,
|
|
4845
|
+
// markPrice: unRealizedPrice,
|
|
4846
|
+
markPrice: item.index_price
|
|
4847
|
+
});
|
|
4848
|
+
unrealPnlROI_index = positions.unrealizedPnLROI({
|
|
4849
|
+
positionQty: item.position_qty,
|
|
4850
|
+
openPrice: item.average_open_price,
|
|
4851
|
+
IMR: imr,
|
|
4852
|
+
unrealizedPnL: unrealPnl_index
|
|
4853
|
+
});
|
|
4854
|
+
}
|
|
4855
|
+
const unsettlementPnL2 = positions.unsettlementPnL({
|
|
4856
|
+
positionQty: item.position_qty,
|
|
4857
|
+
markPrice: item.mark_price,
|
|
4858
|
+
costPosition: item.cost_position,
|
|
4859
|
+
sumUnitaryFunding: propOr(
|
|
4860
|
+
0,
|
|
4861
|
+
"sum_unitary_funding",
|
|
4862
|
+
fundingRates[item.symbol]
|
|
4863
|
+
),
|
|
4864
|
+
lastSumUnitaryFunding: item.last_sum_unitary_funding
|
|
4865
|
+
});
|
|
4866
|
+
const MMR = positions.MMR({
|
|
4867
|
+
baseMMR: info?.["base_mmr"],
|
|
4868
|
+
baseIMR: info?.["base_imr"],
|
|
4869
|
+
IMRFactor: accountInfo.imr_factor[item.symbol],
|
|
4870
|
+
positionNotional: notional,
|
|
4871
|
+
IMR_factor_power: 4 / 5
|
|
4872
|
+
});
|
|
4873
|
+
unrealPnL_total = unrealPnL_total.add(unrealPnl);
|
|
4874
|
+
unrealPnL_total_index = unrealPnL_total_index.add(unrealPnl_index);
|
|
4875
|
+
notional_total = notional_total.add(notional);
|
|
4876
|
+
unsettlementPnL_total = unsettlementPnL_total.add(unsettlementPnL2);
|
|
4877
|
+
const fundingFee = new Decimal(sum_unitary_funding).sub(item.last_sum_unitary_funding).mul(item.position_qty).negated().toNumber();
|
|
4835
4878
|
return {
|
|
4836
4879
|
...item,
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4880
|
+
fundingFee,
|
|
4881
|
+
mm: positions.maintenanceMargin({
|
|
4882
|
+
positionQty: item.position_qty,
|
|
4883
|
+
markPrice: item.mark_price,
|
|
4884
|
+
MMR
|
|
4885
|
+
}),
|
|
4886
|
+
mmr: MMR,
|
|
4887
|
+
notional,
|
|
4888
|
+
unsettlement_pnl: unsettlementPnL2,
|
|
4889
|
+
unrealized_pnl: unrealPnl,
|
|
4890
|
+
unrealized_pnl_index: unrealPnl_index,
|
|
4891
|
+
unrealized_pnl_ROI: unrealPnlROI,
|
|
4892
|
+
unrealized_pnl_ROI_index: unrealPnlROI_index
|
|
4842
4893
|
};
|
|
4843
4894
|
});
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
if (symbolsInfo) {
|
|
4862
|
-
imr = symbolsInfo?.[element.symbol]("base_imr");
|
|
4863
|
-
}
|
|
4864
|
-
filter[index] = {
|
|
4865
|
-
...filter[index],
|
|
4866
|
-
isFavorite,
|
|
4867
|
-
tabs,
|
|
4868
|
-
leverage: imr ? 1 / imr : void 0
|
|
4895
|
+
const totalUnrealPnl = unrealPnL_total.toNumber();
|
|
4896
|
+
const totalUnrealPnl_index = unrealPnL_total_index.toNumber();
|
|
4897
|
+
const unsettlementPnL = unsettlementPnL_total.toNumber();
|
|
4898
|
+
let totalUnrealizedROI = 0, totalUnrealizedROI_index = 0;
|
|
4899
|
+
if (portfolio) {
|
|
4900
|
+
const { totalValue, totalCollateral } = portfolio;
|
|
4901
|
+
rows = rows.map((item) => {
|
|
4902
|
+
const est_liq_price = positions.liqPrice({
|
|
4903
|
+
markPrice: item.mark_price,
|
|
4904
|
+
totalCollateral: totalCollateral.toNumber(),
|
|
4905
|
+
positionQty: item.position_qty,
|
|
4906
|
+
positions: rows,
|
|
4907
|
+
MMR: item.mmr
|
|
4908
|
+
});
|
|
4909
|
+
return {
|
|
4910
|
+
...item,
|
|
4911
|
+
est_liq_price
|
|
4869
4912
|
};
|
|
4913
|
+
});
|
|
4914
|
+
if (totalValue !== null && !totalValue.eq(zero)) {
|
|
4915
|
+
totalUnrealizedROI = account.totalUnrealizedROI({
|
|
4916
|
+
totalUnrealizedPnL: totalUnrealPnl,
|
|
4917
|
+
totalValue: totalValue.toNumber()
|
|
4918
|
+
});
|
|
4919
|
+
totalUnrealizedROI_index = account.totalUnrealizedROI({
|
|
4920
|
+
totalUnrealizedPnL: totalUnrealPnl_index,
|
|
4921
|
+
totalValue: totalValue.toNumber()
|
|
4922
|
+
});
|
|
4870
4923
|
}
|
|
4871
4924
|
}
|
|
4872
|
-
return
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4925
|
+
return {
|
|
4926
|
+
...data,
|
|
4927
|
+
unrealPnL: totalUnrealPnl,
|
|
4928
|
+
total_unreal_pnl: totalUnrealPnl,
|
|
4929
|
+
total_unreal_pnl_index: totalUnrealPnl_index,
|
|
4930
|
+
notional: notional_total.toNumber(),
|
|
4931
|
+
unsettledPnL: unsettlementPnL,
|
|
4932
|
+
total_unsettled_pnl: unsettlementPnL,
|
|
4933
|
+
unrealPnlROI: totalUnrealizedROI,
|
|
4934
|
+
unrealPnlROI_index: totalUnrealizedROI_index,
|
|
4935
|
+
rows
|
|
4936
|
+
};
|
|
4937
|
+
}
|
|
4938
|
+
preprocess(data) {
|
|
4939
|
+
let rows = data.rows;
|
|
4940
|
+
if (this.symbol !== AllPositions && Array.isArray(rows)) {
|
|
4941
|
+
rows = rows.filter((item) => item.symbol === this.symbol);
|
|
4883
4942
|
}
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
};
|
|
4888
|
-
const updateSelectedFavoriteTab = (tab) => {
|
|
4889
|
-
updateStore("lastSelectedFavoriteTab", tab);
|
|
4890
|
-
};
|
|
4891
|
-
const updateTabsSortState = (tabId, sortKey, sortOrder) => {
|
|
4892
|
-
const map = getStore("tabSort", {});
|
|
4893
|
-
map[tabId] = {
|
|
4894
|
-
sortKey,
|
|
4895
|
-
sortOrder
|
|
4943
|
+
return {
|
|
4944
|
+
...data,
|
|
4945
|
+
rows
|
|
4896
4946
|
};
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
markets || EMPTY_LIST,
|
|
4903
|
-
{
|
|
4904
|
-
favoriteTabs,
|
|
4905
|
-
favorites,
|
|
4906
|
-
recent,
|
|
4907
|
-
tabSort,
|
|
4908
|
-
addToHistory,
|
|
4909
|
-
updateFavorites,
|
|
4910
|
-
updateFavoriteTabs,
|
|
4911
|
-
updateSymbolFavoriteState,
|
|
4912
|
-
pinToTop,
|
|
4913
|
-
getLastSelFavTab,
|
|
4914
|
-
updateSelectedFavoriteTab,
|
|
4915
|
-
updateTabsSortState
|
|
4947
|
+
}
|
|
4948
|
+
getPosition(_, ctx) {
|
|
4949
|
+
const positions3 = ctx.get((output) => output[this.name]) || usePositionStore.getState().positions[this.symbol];
|
|
4950
|
+
if (this.symbol === AllPositions) {
|
|
4951
|
+
return positions3;
|
|
4916
4952
|
}
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
if (est_funding_rate === void 0 || est_funding_rate === null) {
|
|
4922
|
-
return null;
|
|
4953
|
+
if (positions3 && Array.isArray(positions3.rows)) {
|
|
4954
|
+
return positions3;
|
|
4955
|
+
}
|
|
4956
|
+
return this.preprocess(this.getAllPositions(ctx));
|
|
4923
4957
|
}
|
|
4924
|
-
|
|
4925
|
-
|
|
4958
|
+
destroy() {
|
|
4959
|
+
usePositionStore.getState().actions.closePosition(this.symbol);
|
|
4960
|
+
CalculatorContext.instance?.deleteByName(this.name);
|
|
4926
4961
|
}
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
function get24hChange2(close, open) {
|
|
4930
|
-
if (close !== void 0 && open !== void 0) {
|
|
4931
|
-
if (open === 0) {
|
|
4932
|
-
return 0;
|
|
4933
|
-
}
|
|
4934
|
-
return new Decimal(close).minus(open).div(open).toNumber();
|
|
4962
|
+
getAllPositions(ctx) {
|
|
4963
|
+
return ctx.get((output) => output[AllPositions]) || usePositionStore.getState().positions[AllPositions];
|
|
4935
4964
|
}
|
|
4936
|
-
}
|
|
4937
|
-
|
|
4938
|
-
// src/orderly/useMarkPricesStream.ts
|
|
4939
|
-
var useMarkPricesStream = () => {
|
|
4940
|
-
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4941
|
-
return { data };
|
|
4942
|
-
};
|
|
4943
|
-
|
|
4944
|
-
// src/orderly/useIndexPricesStream.ts
|
|
4945
|
-
var useIndexPricesStream = () => {
|
|
4946
|
-
const indexPrices = useIndexPriceStore((state) => state.indexPrices);
|
|
4947
|
-
const getIndexPrice = (token) => {
|
|
4948
|
-
if (token === "USDC") {
|
|
4949
|
-
return 1;
|
|
4950
|
-
}
|
|
4951
|
-
return indexPrices[`PERP_${token}_USDC`] ?? 0;
|
|
4952
|
-
};
|
|
4953
|
-
return {
|
|
4954
|
-
data: indexPrices,
|
|
4955
|
-
getIndexPrice: useMemoizedFn(getIndexPrice)
|
|
4956
|
-
};
|
|
4957
4965
|
};
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
const parts = 5;
|
|
4961
|
-
const step = (max2 - min2) / (parts - 1);
|
|
4962
|
-
const result = [];
|
|
4963
|
-
for (let i = 0; i < parts; i++) {
|
|
4964
|
-
result.push(Math.floor(min2 + step * i));
|
|
4965
|
-
}
|
|
4966
|
-
return result;
|
|
4966
|
+
PositionCalculator.logPosition = (symbol = "all") => {
|
|
4967
|
+
return usePositionStore.getState().positions[symbol];
|
|
4967
4968
|
};
|
|
4968
|
-
var
|
|
4969
|
-
const
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4969
|
+
var parseHolding = (holding, indexPrices, tokensInfo) => {
|
|
4970
|
+
const nonUSDC = [];
|
|
4971
|
+
let USDC_holding = 0;
|
|
4972
|
+
holding.forEach((item) => {
|
|
4973
|
+
if (item.token === "USDC") {
|
|
4974
|
+
USDC_holding = item.holding;
|
|
4975
|
+
} else {
|
|
4976
|
+
const tokenInfo = tokensInfo.find(({ token }) => token === item.token);
|
|
4977
|
+
const {
|
|
4978
|
+
base_weight = 0,
|
|
4979
|
+
discount_factor = 0,
|
|
4980
|
+
user_max_qty = 0
|
|
4981
|
+
} = tokenInfo || {};
|
|
4982
|
+
const holdingQty = item?.holding ?? 0;
|
|
4983
|
+
const indexPrice = indexPrices[`PERP_${item.token}_USDC`] ?? 0;
|
|
4984
|
+
const collateralRatio4 = account.collateralRatio({
|
|
4985
|
+
baseWeight: base_weight,
|
|
4986
|
+
discountFactor: discount_factor,
|
|
4987
|
+
collateralQty: holdingQty,
|
|
4988
|
+
collateralCap: user_max_qty,
|
|
4989
|
+
indexPrice
|
|
4990
|
+
});
|
|
4991
|
+
nonUSDC.push({
|
|
4992
|
+
holding: holdingQty,
|
|
4993
|
+
indexPrice,
|
|
4994
|
+
collateralCap: user_max_qty,
|
|
4995
|
+
collateralRatio: collateralRatio4
|
|
4996
|
+
});
|
|
4973
4997
|
}
|
|
4974
|
-
);
|
|
4975
|
-
const [update, { isMutating }] = useMutation("/v1/client/leverage");
|
|
4976
|
-
const { data: leverageConfig, isLoading } = useQuery("/v1/public/leverage", {
|
|
4977
|
-
revalidateOnFocus: false,
|
|
4978
|
-
errorRetryCount: 3
|
|
4979
|
-
// formatter: (data) => data,
|
|
4980
4998
|
});
|
|
4981
|
-
|
|
4982
|
-
async (data2) => {
|
|
4983
|
-
const res = await update(data2);
|
|
4984
|
-
if (res.success) {
|
|
4985
|
-
return mutate6();
|
|
4986
|
-
} else {
|
|
4987
|
-
throw new Error(res.message);
|
|
4988
|
-
}
|
|
4989
|
-
},
|
|
4990
|
-
[update, mutate6]
|
|
4991
|
-
);
|
|
4992
|
-
const memoizedCurLeverage = useMemo(() => {
|
|
4993
|
-
if (data?.max_leverage !== void 0) {
|
|
4994
|
-
return Number(data.max_leverage);
|
|
4995
|
-
}
|
|
4996
|
-
return 1;
|
|
4997
|
-
}, [data?.max_leverage]);
|
|
4998
|
-
const memoizedMaxLeverage = useMemo(() => {
|
|
4999
|
-
if (leverageConfig?.max_futures_leverage !== void 0) {
|
|
5000
|
-
return Number(leverageConfig.max_futures_leverage);
|
|
5001
|
-
}
|
|
5002
|
-
return 1;
|
|
5003
|
-
}, [leverageConfig?.max_futures_leverage]);
|
|
5004
|
-
const memoizedLeverageLevers = useMemo(() => {
|
|
5005
|
-
return generateLeverageLevers(memoizedMaxLeverage);
|
|
5006
|
-
}, [memoizedMaxLeverage]);
|
|
5007
|
-
return {
|
|
5008
|
-
update: updateLeverage,
|
|
5009
|
-
isLoading: isLoading || isMutating,
|
|
5010
|
-
leverageLevers: memoizedLeverageLevers,
|
|
5011
|
-
curLeverage: memoizedCurLeverage,
|
|
5012
|
-
maxLeverage: memoizedMaxLeverage
|
|
5013
|
-
};
|
|
4999
|
+
return [USDC_holding, nonUSDC];
|
|
5014
5000
|
};
|
|
5015
5001
|
|
|
5016
|
-
// src/orderly/
|
|
5017
|
-
var
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
const { input, token } = options;
|
|
5023
|
-
const isUSDC = token?.toUpperCase() === "USDC";
|
|
5024
|
-
const tokensInfo = useTokensInfo();
|
|
5025
|
-
const { usdc, data: holdingList = [] } = useHoldingStream();
|
|
5026
|
-
const { getIndexPrice } = useIndexPricesStream();
|
|
5027
|
-
const { unsettledPnL } = useCollateral();
|
|
5028
|
-
const usdcBalance = useMemo(() => {
|
|
5029
|
-
if (isUSDC && input) {
|
|
5030
|
-
return new Decimal(usdc?.holding ?? 0).add(input).toNumber();
|
|
5031
|
-
}
|
|
5032
|
-
return usdc?.holding ?? 0;
|
|
5033
|
-
}, [usdc?.holding, input, isUSDC]);
|
|
5034
|
-
const getAdjustedQty = useCallback(
|
|
5035
|
-
(item) => {
|
|
5036
|
-
if (input && item.token === token) {
|
|
5037
|
-
return new Decimal(item?.holding ?? 0).add(input).toNumber();
|
|
5038
|
-
}
|
|
5039
|
-
return item?.holding ?? 0;
|
|
5040
|
-
},
|
|
5041
|
-
[input, token]
|
|
5042
|
-
);
|
|
5043
|
-
const memoizedLTV = useMemo(() => {
|
|
5044
|
-
return LTV({
|
|
5045
|
-
usdcBalance,
|
|
5046
|
-
upnl: unsettledPnL,
|
|
5047
|
-
assets: holdingList.filter((h) => h.token.toUpperCase() !== "USDC").map((item) => {
|
|
5048
|
-
const indexPrice = getIndexPrice(item.token);
|
|
5049
|
-
const findToken = tokensInfo?.find((i) => i.token === item.token);
|
|
5050
|
-
const qty = getAdjustedQty(item);
|
|
5051
|
-
const weight = collateralRatio({
|
|
5052
|
-
baseWeight: findToken?.base_weight ?? 0,
|
|
5053
|
-
discountFactor: findToken?.discount_factor ?? 0,
|
|
5054
|
-
collateralCap: findToken?.user_max_qty ?? qty,
|
|
5055
|
-
collateralQty: qty,
|
|
5056
|
-
indexPrice
|
|
5057
|
-
});
|
|
5058
|
-
return {
|
|
5059
|
-
qty,
|
|
5060
|
-
indexPrice,
|
|
5061
|
-
weight: weight.toNumber()
|
|
5062
|
-
};
|
|
5063
|
-
})
|
|
5064
|
-
});
|
|
5065
|
-
}, [
|
|
5066
|
-
usdcBalance,
|
|
5067
|
-
unsettledPnL,
|
|
5068
|
-
holdingList,
|
|
5069
|
-
tokensInfo,
|
|
5070
|
-
getIndexPrice,
|
|
5071
|
-
getAdjustedQty
|
|
5072
|
-
]);
|
|
5073
|
-
if (new Decimal(usdcBalance).add(new Decimal(unsettledPnL)).gte(zero)) {
|
|
5074
|
-
return 0;
|
|
5075
|
-
}
|
|
5076
|
-
return new Decimal(memoizedLTV).mul(100).toDecimalPlaces(2, Decimal.ROUND_DOWN).toNumber();
|
|
5077
|
-
};
|
|
5078
|
-
var useFundingRate = (symbol) => {
|
|
5079
|
-
if (!symbol) {
|
|
5080
|
-
throw new SDKError("Symbol is required");
|
|
5002
|
+
// src/orderly/calculator/indexPrice.ts
|
|
5003
|
+
var IndexPriceCalculatorName = "indexPriceCalculator";
|
|
5004
|
+
var IndexPriceCalculator = class extends BaseCalculator {
|
|
5005
|
+
constructor() {
|
|
5006
|
+
super(...arguments);
|
|
5007
|
+
this.name = IndexPriceCalculatorName;
|
|
5081
5008
|
}
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
fallbackData: {
|
|
5088
|
-
est_funding_rate: 0,
|
|
5089
|
-
next_funing_time: 0
|
|
5090
|
-
}
|
|
5091
|
-
}
|
|
5092
|
-
);
|
|
5093
|
-
useEffect(() => {
|
|
5094
|
-
if (!data || isLoading) {
|
|
5009
|
+
calc(scope, data, ctx) {
|
|
5010
|
+
return data;
|
|
5011
|
+
}
|
|
5012
|
+
update(data) {
|
|
5013
|
+
if (!data)
|
|
5095
5014
|
return;
|
|
5015
|
+
useIndexPriceStore.getState().actions.updateIndexPrice(data);
|
|
5016
|
+
}
|
|
5017
|
+
static getValue() {
|
|
5018
|
+
return useIndexPriceStore.getState().indexPrices;
|
|
5019
|
+
}
|
|
5020
|
+
};
|
|
5021
|
+
|
|
5022
|
+
// src/orderly/calculator/portfolio.ts
|
|
5023
|
+
var PortfolioCalculatorName = "portfolio";
|
|
5024
|
+
var PortfolioCalculator = class extends BaseCalculator {
|
|
5025
|
+
constructor() {
|
|
5026
|
+
super(...arguments);
|
|
5027
|
+
this.name = PortfolioCalculatorName;
|
|
5028
|
+
}
|
|
5029
|
+
calc(scope, data, ctx) {
|
|
5030
|
+
let markPrices;
|
|
5031
|
+
let indexPrices;
|
|
5032
|
+
const portfolio = this.getPortfolio(ctx);
|
|
5033
|
+
if (scope === "markPrice" /* MARK_PRICE */) {
|
|
5034
|
+
markPrices = data;
|
|
5035
|
+
} else {
|
|
5036
|
+
markPrices = ctx.get(
|
|
5037
|
+
(cache) => cache[MarketCalculatorName]
|
|
5038
|
+
);
|
|
5096
5039
|
}
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5040
|
+
if (scope === "indexPrice" /* INDEX_PRICE */) {
|
|
5041
|
+
indexPrices = data;
|
|
5042
|
+
} else {
|
|
5043
|
+
indexPrices = ctx.get(
|
|
5044
|
+
(cache) => cache[IndexPriceCalculatorName]
|
|
5045
|
+
);
|
|
5100
5046
|
}
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
clearInterval(timerRef.current);
|
|
5047
|
+
const positions3 = ctx.get(
|
|
5048
|
+
(output) => output.positionCalculator_all
|
|
5049
|
+
);
|
|
5050
|
+
let holding = portfolio.holding;
|
|
5051
|
+
if (scope === "portfolio" /* PORTFOLIO */ && data.holding && Array.isArray(holding)) {
|
|
5052
|
+
if (Array.isArray(data.holding)) {
|
|
5053
|
+
holding = data.holding;
|
|
5054
|
+
} else {
|
|
5055
|
+
holding = holding.map((item) => {
|
|
5056
|
+
if (data.holding[item.token]) {
|
|
5057
|
+
return {
|
|
5058
|
+
...item,
|
|
5059
|
+
holding: data.holding[item.token].holding,
|
|
5060
|
+
frozen: data.holding[item.token].frozen
|
|
5061
|
+
};
|
|
5062
|
+
}
|
|
5063
|
+
return item;
|
|
5064
|
+
});
|
|
5120
5065
|
}
|
|
5121
|
-
};
|
|
5122
|
-
}, [data, isLoading]);
|
|
5123
|
-
const est_funding_rate = useMemo(() => {
|
|
5124
|
-
if (!data) {
|
|
5125
|
-
return;
|
|
5126
5066
|
}
|
|
5127
|
-
const
|
|
5128
|
-
|
|
5067
|
+
const accountInfo = ctx.accountInfo;
|
|
5068
|
+
const symbolsInfo = ctx.symbolsInfo;
|
|
5069
|
+
const tokensInfo = ctx.tokensInfo;
|
|
5070
|
+
return this.format({
|
|
5071
|
+
holding,
|
|
5072
|
+
positions: positions3,
|
|
5073
|
+
markPrices,
|
|
5074
|
+
accountInfo,
|
|
5075
|
+
symbolsInfo,
|
|
5076
|
+
indexPrices,
|
|
5077
|
+
tokensInfo: tokensInfo ?? EMPTY_LIST
|
|
5078
|
+
});
|
|
5079
|
+
}
|
|
5080
|
+
getPortfolio(ctx) {
|
|
5081
|
+
return ctx.get((output) => output[this.name]) || useAppStore.getState().portfolio;
|
|
5082
|
+
}
|
|
5083
|
+
format(inputs) {
|
|
5084
|
+
const {
|
|
5085
|
+
holding,
|
|
5086
|
+
positions: positions3,
|
|
5087
|
+
markPrices,
|
|
5088
|
+
indexPrices,
|
|
5089
|
+
accountInfo,
|
|
5090
|
+
symbolsInfo,
|
|
5091
|
+
tokensInfo
|
|
5092
|
+
} = inputs;
|
|
5093
|
+
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo) {
|
|
5129
5094
|
return null;
|
|
5130
5095
|
}
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5096
|
+
const unsettledPnL = pathOr(0, ["total_unsettled_pnl"])(positions3);
|
|
5097
|
+
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
5098
|
+
const [USDC_holding, nonUSDC] = parseHolding(
|
|
5099
|
+
holding,
|
|
5100
|
+
indexPrices,
|
|
5101
|
+
tokensInfo
|
|
5134
5102
|
);
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5103
|
+
const usdc = holding.find((item) => item.token === "USDC");
|
|
5104
|
+
const totalCollateral = account.totalCollateral({
|
|
5105
|
+
USDCHolding: USDC_holding,
|
|
5106
|
+
nonUSDCHolding: nonUSDC,
|
|
5107
|
+
unsettlementPnL: unsettledPnL
|
|
5108
|
+
});
|
|
5109
|
+
const totalValue = account.totalValue({
|
|
5110
|
+
totalUnsettlementPnL: unsettledPnL,
|
|
5111
|
+
USDCHolding: USDC_holding,
|
|
5112
|
+
nonUSDCHolding: nonUSDC
|
|
5113
|
+
});
|
|
5114
|
+
const totalUnrealizedROI = account.totalUnrealizedROI({
|
|
5115
|
+
totalUnrealizedPnL: unrealizedPnL,
|
|
5116
|
+
totalValue: totalValue.toNumber()
|
|
5117
|
+
});
|
|
5118
|
+
const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
|
|
5119
|
+
positions: positions3.rows,
|
|
5120
|
+
markPrices,
|
|
5121
|
+
IMR_Factors: accountInfo.imr_factor,
|
|
5122
|
+
maxLeverage: accountInfo.max_leverage,
|
|
5123
|
+
symbolInfo: createGetter({ ...symbolsInfo })
|
|
5124
|
+
});
|
|
5125
|
+
const freeCollateral = account.freeCollateral({
|
|
5126
|
+
totalCollateral,
|
|
5127
|
+
totalInitialMarginWithOrders
|
|
5128
|
+
});
|
|
5129
|
+
const availableBalance = account.availableBalance({
|
|
5130
|
+
USDCHolding: usdc?.holding ?? 0,
|
|
5131
|
+
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
5132
|
+
});
|
|
5133
|
+
return {
|
|
5134
|
+
totalCollateral,
|
|
5135
|
+
totalValue,
|
|
5136
|
+
totalUnrealizedROI,
|
|
5137
|
+
freeCollateral,
|
|
5138
|
+
availableBalance,
|
|
5139
|
+
unsettledPnL,
|
|
5140
|
+
holding
|
|
5141
|
+
};
|
|
5145
5142
|
}
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5143
|
+
update(data, scope) {
|
|
5144
|
+
if (data) {
|
|
5145
|
+
useAppStore.getState().actions.batchUpdateForPortfolio({
|
|
5146
|
+
totalCollateral: data.totalCollateral,
|
|
5147
|
+
totalValue: data.totalValue,
|
|
5148
|
+
freeCollateral: data.freeCollateral,
|
|
5149
|
+
availableBalance: data.availableBalance,
|
|
5150
|
+
totalUnrealizedROI: data.totalUnrealizedROI,
|
|
5151
|
+
unsettledPnL: data.unsettledPnL,
|
|
5152
|
+
holding: Array.isArray(data.holding) ? data.holding : []
|
|
5153
|
+
});
|
|
5154
|
+
}
|
|
5154
5155
|
}
|
|
5155
|
-
const daysMap = {
|
|
5156
|
-
"1d": 1,
|
|
5157
|
-
"3d": 3,
|
|
5158
|
-
"7d": 7,
|
|
5159
|
-
"14d": 14,
|
|
5160
|
-
"30d": 30,
|
|
5161
|
-
"90d": 90
|
|
5162
|
-
};
|
|
5163
|
-
const totalTimes = daysMap[period] * 3;
|
|
5164
|
-
return periodData.positive / totalTimes;
|
|
5165
5156
|
};
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
);
|
|
5170
|
-
const
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5157
|
+
|
|
5158
|
+
// src/useCalculatorService.ts
|
|
5159
|
+
var useCalculatorService = () => {
|
|
5160
|
+
const { get: get3 } = useSimpleDI();
|
|
5161
|
+
const calculatorService = useConstant(() => {
|
|
5162
|
+
let calculatorService2 = get3(CalculatorServiceID);
|
|
5163
|
+
if (!calculatorService2) {
|
|
5164
|
+
const positionCalculator = new PositionCalculator();
|
|
5165
|
+
const portfolioCalculator = new PortfolioCalculator();
|
|
5166
|
+
const markPriceCalculator = new MarkPriceCalculator();
|
|
5167
|
+
const indexPriceCalculator = new IndexPriceCalculator();
|
|
5168
|
+
calculatorService2 = new CalculatorService(new ShardingScheduler(), [
|
|
5169
|
+
[
|
|
5170
|
+
"markPrice" /* MARK_PRICE */,
|
|
5171
|
+
[
|
|
5172
|
+
markPriceCalculator,
|
|
5173
|
+
positionCalculator,
|
|
5174
|
+
portfolioCalculator,
|
|
5175
|
+
positionCalculator
|
|
5176
|
+
]
|
|
5177
|
+
],
|
|
5178
|
+
["position" /* POSITION */, [positionCalculator, portfolioCalculator]],
|
|
5179
|
+
["portfolio" /* PORTFOLIO */, [portfolioCalculator]],
|
|
5180
|
+
// indexPrice
|
|
5181
|
+
[
|
|
5182
|
+
"indexPrice" /* INDEX_PRICE */,
|
|
5183
|
+
[indexPriceCalculator, positionCalculator]
|
|
5184
|
+
]
|
|
5185
|
+
]);
|
|
5186
|
+
SimpleDI.registerByName(CalculatorServiceID, calculatorService2);
|
|
5187
|
+
}
|
|
5188
|
+
return calculatorService2;
|
|
5189
|
+
});
|
|
5190
|
+
return calculatorService;
|
|
5195
5191
|
};
|
|
5192
|
+
|
|
5193
|
+
// src/orderly/usePositionStream/usePositionStream.ts
|
|
5196
5194
|
var scopes = [
|
|
5197
5195
|
"position" /* POSITION */,
|
|
5198
5196
|
"markPrice" /* MARK_PRICE */,
|
|
@@ -7118,6 +7116,252 @@ var useSettleSubscription = (options) => {
|
|
|
7118
7116
|
}
|
|
7119
7117
|
);
|
|
7120
7118
|
};
|
|
7119
|
+
var usePrivateDataObserver = (options) => {
|
|
7120
|
+
const ws = useWS();
|
|
7121
|
+
const ee = useEventEmitter();
|
|
7122
|
+
const { state, account: account9 } = useAccount();
|
|
7123
|
+
const { setAccountInfo, restoreHolding, cleanAll } = useAppStore(
|
|
7124
|
+
(state2) => state2.actions
|
|
7125
|
+
);
|
|
7126
|
+
const statusActions = useApiStatusActions();
|
|
7127
|
+
const calculatorService = useCalculatorService();
|
|
7128
|
+
const positionsActions = usePositionActions();
|
|
7129
|
+
const { data: clientInfo } = usePrivateQuery(
|
|
7130
|
+
"/v1/client/info",
|
|
7131
|
+
{
|
|
7132
|
+
revalidateOnFocus: false
|
|
7133
|
+
}
|
|
7134
|
+
);
|
|
7135
|
+
useEffect(() => {
|
|
7136
|
+
if (clientInfo) {
|
|
7137
|
+
setAccountInfo(clientInfo);
|
|
7138
|
+
}
|
|
7139
|
+
}, [clientInfo, setAccountInfo]);
|
|
7140
|
+
const { data: positions3, isLoading: isPositionLoading } = usePrivateQuery("/v1/positions", {
|
|
7141
|
+
formatter: (data) => data,
|
|
7142
|
+
onError: (error) => {
|
|
7143
|
+
statusActions.updateApiError("positions", error.message);
|
|
7144
|
+
}
|
|
7145
|
+
// revalidateOnFocus: false,
|
|
7146
|
+
});
|
|
7147
|
+
useEffect(() => {
|
|
7148
|
+
const handler = (state2) => {
|
|
7149
|
+
if (!state2.accountId) {
|
|
7150
|
+
calculatorService.stop();
|
|
7151
|
+
cleanAll();
|
|
7152
|
+
positionsActions.clearAll();
|
|
7153
|
+
}
|
|
7154
|
+
};
|
|
7155
|
+
account9.on(EVENT_NAMES.statusChanged, handler);
|
|
7156
|
+
return () => {
|
|
7157
|
+
account9.off(EVENT_NAMES.statusChanged, handler);
|
|
7158
|
+
};
|
|
7159
|
+
}, []);
|
|
7160
|
+
useEffect(() => {
|
|
7161
|
+
if (isPositionLoading) {
|
|
7162
|
+
statusActions.updateApiLoading("positions", isPositionLoading);
|
|
7163
|
+
}
|
|
7164
|
+
}, [isPositionLoading, statusActions]);
|
|
7165
|
+
useEffect(() => {
|
|
7166
|
+
if (positions3 && Array.isArray(positions3.rows)) {
|
|
7167
|
+
calculatorService.calc("position" /* POSITION */, positions3);
|
|
7168
|
+
}
|
|
7169
|
+
}, [calculatorService, positions3]);
|
|
7170
|
+
const { data: holding } = usePrivateQuery(
|
|
7171
|
+
"/v1/client/holding",
|
|
7172
|
+
{
|
|
7173
|
+
formatter: (data) => data.holding
|
|
7174
|
+
// revalidateOnFocus: false,
|
|
7175
|
+
}
|
|
7176
|
+
);
|
|
7177
|
+
useEffect(() => {
|
|
7178
|
+
if (!account9.accountId)
|
|
7179
|
+
return;
|
|
7180
|
+
const unsubscribe = ws.privateSubscribe(
|
|
7181
|
+
{
|
|
7182
|
+
id: "balance",
|
|
7183
|
+
event: "subscribe",
|
|
7184
|
+
topic: "balance",
|
|
7185
|
+
ts: Date.now()
|
|
7186
|
+
},
|
|
7187
|
+
{
|
|
7188
|
+
onMessage: (data) => {
|
|
7189
|
+
const holding2 = data?.balances ?? {};
|
|
7190
|
+
if (holding2) {
|
|
7191
|
+
calculatorService.calc("portfolio" /* PORTFOLIO */, { holding: holding2 });
|
|
7192
|
+
}
|
|
7193
|
+
}
|
|
7194
|
+
}
|
|
7195
|
+
);
|
|
7196
|
+
return () => unsubscribe?.();
|
|
7197
|
+
}, [account9.accountId]);
|
|
7198
|
+
const isHoldingInit = useRef(false);
|
|
7199
|
+
useEffect(() => {
|
|
7200
|
+
isHoldingInit.current = false;
|
|
7201
|
+
}, [state.address]);
|
|
7202
|
+
useEffect(() => {
|
|
7203
|
+
if (!holding) {
|
|
7204
|
+
return;
|
|
7205
|
+
}
|
|
7206
|
+
if (isHoldingInit.current) {
|
|
7207
|
+
calculatorService.calc("portfolio" /* PORTFOLIO */, { holding });
|
|
7208
|
+
} else {
|
|
7209
|
+
restoreHolding(holding);
|
|
7210
|
+
}
|
|
7211
|
+
isHoldingInit.current = true;
|
|
7212
|
+
}, [holding]);
|
|
7213
|
+
const [subOrder] = useLocalStorage("orderly_subscribe_order", true);
|
|
7214
|
+
const updateOrders = (data, isAlgoOrder) => {
|
|
7215
|
+
const keysMap = options.getKeysMap("orders");
|
|
7216
|
+
const filteredKeys = /* @__PURE__ */ new Map();
|
|
7217
|
+
const keyStartWith = isAlgoOrder ? "algoOrders" : "orders";
|
|
7218
|
+
const keys = keysMap.keys();
|
|
7219
|
+
for (const key of keys) {
|
|
7220
|
+
if (key.startsWith(keyStartWith)) {
|
|
7221
|
+
filteredKeys.set(key, keysMap.get(key));
|
|
7222
|
+
}
|
|
7223
|
+
}
|
|
7224
|
+
let fieldChanges = {};
|
|
7225
|
+
filteredKeys.forEach((getKey, key) => {
|
|
7226
|
+
mutate(
|
|
7227
|
+
unstable_serialize((index, prevData) => [
|
|
7228
|
+
getKey(index, prevData),
|
|
7229
|
+
state.accountId
|
|
7230
|
+
]),
|
|
7231
|
+
(prevData) => {
|
|
7232
|
+
try {
|
|
7233
|
+
if (isAlgoOrder) {
|
|
7234
|
+
const res = updateAlgoOrdersHandler(
|
|
7235
|
+
key,
|
|
7236
|
+
data,
|
|
7237
|
+
prevData
|
|
7238
|
+
);
|
|
7239
|
+
fieldChanges = res?.fieldChanges || {};
|
|
7240
|
+
return res?.mergedOrders;
|
|
7241
|
+
}
|
|
7242
|
+
return updateOrdersHandler(key, data, prevData);
|
|
7243
|
+
} catch (error) {
|
|
7244
|
+
return prevData;
|
|
7245
|
+
}
|
|
7246
|
+
},
|
|
7247
|
+
{
|
|
7248
|
+
revalidate: false
|
|
7249
|
+
}
|
|
7250
|
+
);
|
|
7251
|
+
});
|
|
7252
|
+
const formattedData = isAlgoOrder ? AlgoOrderMergeHandler.groupOrders(data) : object2underscore(data);
|
|
7253
|
+
ee.emit("orders:changed", {
|
|
7254
|
+
...formattedData,
|
|
7255
|
+
status: isAlgoOrder ? formattedData.algo_status : data.status,
|
|
7256
|
+
// custom field name
|
|
7257
|
+
fieldChanges
|
|
7258
|
+
});
|
|
7259
|
+
};
|
|
7260
|
+
useEffect(() => {
|
|
7261
|
+
if (!state.accountId) {
|
|
7262
|
+
return;
|
|
7263
|
+
}
|
|
7264
|
+
if (subOrder !== true) {
|
|
7265
|
+
return;
|
|
7266
|
+
}
|
|
7267
|
+
const unsubscribe = ws.privateSubscribe("executionreport", {
|
|
7268
|
+
onMessage: (data) => {
|
|
7269
|
+
updateOrders(data, false);
|
|
7270
|
+
}
|
|
7271
|
+
});
|
|
7272
|
+
return () => unsubscribe?.();
|
|
7273
|
+
}, [state.accountId, subOrder]);
|
|
7274
|
+
useEffect(() => {
|
|
7275
|
+
if (!state.accountId)
|
|
7276
|
+
return;
|
|
7277
|
+
if (subOrder !== true)
|
|
7278
|
+
return;
|
|
7279
|
+
const unsubscribe = ws.privateSubscribe("algoexecutionreport", {
|
|
7280
|
+
onMessage: (data) => {
|
|
7281
|
+
updateOrders(data, true);
|
|
7282
|
+
}
|
|
7283
|
+
});
|
|
7284
|
+
return () => unsubscribe?.();
|
|
7285
|
+
}, [state.accountId, subOrder]);
|
|
7286
|
+
useEffect(() => {
|
|
7287
|
+
if (!state.accountId)
|
|
7288
|
+
return;
|
|
7289
|
+
const key = ["/v1/positions", state.accountId];
|
|
7290
|
+
const unsubscribe = ws.privateSubscribe("account", {
|
|
7291
|
+
onMessage: (data) => {
|
|
7292
|
+
const { symbol, leverage } = data?.accountDetail?.symbolLeverage || {};
|
|
7293
|
+
if (symbol && leverage) {
|
|
7294
|
+
mutate(
|
|
7295
|
+
key,
|
|
7296
|
+
(prevPositions) => {
|
|
7297
|
+
if (prevPositions?.rows?.length) {
|
|
7298
|
+
return {
|
|
7299
|
+
...prevPositions,
|
|
7300
|
+
rows: prevPositions.rows.map((row) => {
|
|
7301
|
+
return row.symbol === symbol ? { ...row, leverage } : row;
|
|
7302
|
+
})
|
|
7303
|
+
};
|
|
7304
|
+
}
|
|
7305
|
+
return prevPositions;
|
|
7306
|
+
},
|
|
7307
|
+
{
|
|
7308
|
+
revalidate: false
|
|
7309
|
+
}
|
|
7310
|
+
);
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
7313
|
+
});
|
|
7314
|
+
return () => unsubscribe?.();
|
|
7315
|
+
}, [state.accountId]);
|
|
7316
|
+
useEffect(() => {
|
|
7317
|
+
if (!state.accountId) {
|
|
7318
|
+
return;
|
|
7319
|
+
}
|
|
7320
|
+
const key = ["/v1/positions", state.accountId];
|
|
7321
|
+
const unsubscribe = ws.privateSubscribe("position", {
|
|
7322
|
+
onMessage: (data) => {
|
|
7323
|
+
const { positions: nextPositions } = data;
|
|
7324
|
+
mutate(
|
|
7325
|
+
key,
|
|
7326
|
+
(prevPositions) => {
|
|
7327
|
+
if (!!prevPositions) {
|
|
7328
|
+
const newPositions = {
|
|
7329
|
+
...prevPositions,
|
|
7330
|
+
rows: prevPositions.rows.map((row) => {
|
|
7331
|
+
const itemIndex = nextPositions.findIndex(
|
|
7332
|
+
(item) => item.symbol === row.symbol
|
|
7333
|
+
);
|
|
7334
|
+
if (itemIndex >= 0) {
|
|
7335
|
+
const itemArr = nextPositions.splice(itemIndex, 1);
|
|
7336
|
+
const item = itemArr[0];
|
|
7337
|
+
if (item.averageOpenPrice === 0 && item.positionQty !== 0) {
|
|
7338
|
+
return row;
|
|
7339
|
+
}
|
|
7340
|
+
return object2underscore(item);
|
|
7341
|
+
}
|
|
7342
|
+
return row;
|
|
7343
|
+
})
|
|
7344
|
+
};
|
|
7345
|
+
if (nextPositions.length > 0) {
|
|
7346
|
+
newPositions.rows = [
|
|
7347
|
+
...newPositions.rows,
|
|
7348
|
+
...nextPositions.map(object2underscore)
|
|
7349
|
+
];
|
|
7350
|
+
}
|
|
7351
|
+
return newPositions;
|
|
7352
|
+
}
|
|
7353
|
+
},
|
|
7354
|
+
{
|
|
7355
|
+
revalidate: false
|
|
7356
|
+
}
|
|
7357
|
+
);
|
|
7358
|
+
}
|
|
7359
|
+
});
|
|
7360
|
+
return () => {
|
|
7361
|
+
unsubscribe?.();
|
|
7362
|
+
};
|
|
7363
|
+
}, [state.accountId]);
|
|
7364
|
+
};
|
|
7121
7365
|
var useSymbolPriceRange = (symbol, side, price) => {
|
|
7122
7366
|
const config = useSymbolsInfo();
|
|
7123
7367
|
const priceRange = config?.[symbol]("price_range");
|
|
@@ -7570,12 +7814,12 @@ async function bracketOrderValidator(values, config) {
|
|
|
7570
7814
|
const result = /* @__PURE__ */ Object.create(null);
|
|
7571
7815
|
await Promise.resolve();
|
|
7572
7816
|
const {
|
|
7573
|
-
tp_enable,
|
|
7817
|
+
// tp_enable,
|
|
7818
|
+
// sl_enable,
|
|
7574
7819
|
tp_trigger_price,
|
|
7575
7820
|
tp_order_price,
|
|
7576
7821
|
tp_order_type,
|
|
7577
7822
|
sl_trigger_price,
|
|
7578
|
-
sl_enable,
|
|
7579
7823
|
sl_order_price,
|
|
7580
7824
|
sl_order_type,
|
|
7581
7825
|
side
|
|
@@ -7595,12 +7839,6 @@ async function bracketOrderValidator(values, config) {
|
|
|
7595
7839
|
if (Number(sl_trigger_price) < 0) {
|
|
7596
7840
|
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
7597
7841
|
}
|
|
7598
|
-
if (tp_enable && !tp_trigger_price) {
|
|
7599
|
-
result.tp_trigger_price = OrderValidation.required("tp_trigger_price");
|
|
7600
|
-
}
|
|
7601
|
-
if (sl_enable && !sl_trigger_price) {
|
|
7602
|
-
result.sl_trigger_price = OrderValidation.required("sl_trigger_price");
|
|
7603
|
-
}
|
|
7604
7842
|
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
7605
7843
|
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
7606
7844
|
}
|
|
@@ -8420,8 +8658,8 @@ var BaseAlgoOrderCreator = class {
|
|
|
8420
8658
|
tp_trigger_price,
|
|
8421
8659
|
sl_trigger_price,
|
|
8422
8660
|
side,
|
|
8423
|
-
tp_enable,
|
|
8424
|
-
sl_enable,
|
|
8661
|
+
// tp_enable,
|
|
8662
|
+
// sl_enable,
|
|
8425
8663
|
tp_order_type,
|
|
8426
8664
|
sl_order_type,
|
|
8427
8665
|
tp_order_price,
|
|
@@ -8450,12 +8688,6 @@ var BaseAlgoOrderCreator = class {
|
|
|
8450
8688
|
if (Number(sl_trigger_price) < 0) {
|
|
8451
8689
|
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
8452
8690
|
}
|
|
8453
|
-
if (tp_enable && !tp_trigger_price) {
|
|
8454
|
-
result.tp_trigger_price = OrderValidation.required("tp_trigger_price");
|
|
8455
|
-
}
|
|
8456
|
-
if (sl_enable && !sl_trigger_price) {
|
|
8457
|
-
result.sl_trigger_price = OrderValidation.required("sl_trigger_price");
|
|
8458
|
-
}
|
|
8459
8691
|
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
8460
8692
|
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
8461
8693
|
}
|
|
@@ -8966,9 +9198,6 @@ var tpslFields = [
|
|
|
8966
9198
|
"sl_offset_percentage"
|
|
8967
9199
|
];
|
|
8968
9200
|
var isBracketOrder = (order) => {
|
|
8969
|
-
if (order.sl_enable || order.tp_enable) {
|
|
8970
|
-
return true;
|
|
8971
|
-
}
|
|
8972
9201
|
return !!order.tp_trigger_price || !!order.sl_trigger_price;
|
|
8973
9202
|
};
|
|
8974
9203
|
var hasTPSL = (order) => {
|
|
@@ -9498,28 +9727,6 @@ function useSubAccountMaxWithdrawal(options) {
|
|
|
9498
9727
|
}
|
|
9499
9728
|
|
|
9500
9729
|
// src/orderly/useTakeProfitAndStopLoss/useTPSL.ts
|
|
9501
|
-
var checkIsEnableTpSL = (order) => {
|
|
9502
|
-
const result = {
|
|
9503
|
-
tp_enable: true,
|
|
9504
|
-
sl_enable: true
|
|
9505
|
-
};
|
|
9506
|
-
if (!order) {
|
|
9507
|
-
return result;
|
|
9508
|
-
}
|
|
9509
|
-
const tp = order.child_orders.find(
|
|
9510
|
-
(o) => o.algo_type === AlgoOrderType.TAKE_PROFIT && o.is_activated
|
|
9511
|
-
);
|
|
9512
|
-
const sl = order.child_orders.find(
|
|
9513
|
-
(o) => o.algo_type === AlgoOrderType.STOP_LOSS && o.is_activated
|
|
9514
|
-
);
|
|
9515
|
-
if (!tp) {
|
|
9516
|
-
result.tp_enable = false;
|
|
9517
|
-
}
|
|
9518
|
-
if (!sl) {
|
|
9519
|
-
result.sl_enable = false;
|
|
9520
|
-
}
|
|
9521
|
-
return result;
|
|
9522
|
-
};
|
|
9523
9730
|
var useTaskProfitAndStopLossInternal = (position, options) => {
|
|
9524
9731
|
const isEditing = typeof options?.isEditing !== "undefined" ? options.isEditing : !!options?.defaultOrder;
|
|
9525
9732
|
const [order, setOrder] = useState({
|
|
@@ -9534,8 +9741,12 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
|
|
|
9534
9741
|
// quantity:
|
|
9535
9742
|
// options?.defaultOrder?.quantity || Math.abs(position.position_qty),
|
|
9536
9743
|
algo_type: options?.defaultOrder?.algo_type,
|
|
9537
|
-
tp_enable: isEditing
|
|
9538
|
-
|
|
9744
|
+
// tp_enable: isEditing
|
|
9745
|
+
// ? checkIsEnableTpSL(options?.defaultOrder).tp_enable
|
|
9746
|
+
// : options?.tpslEnable?.tp_enable,
|
|
9747
|
+
// sl_enable: isEditing
|
|
9748
|
+
// ? checkIsEnableTpSL(options?.defaultOrder).sl_enable
|
|
9749
|
+
// : options?.tpslEnable?.sl_enable,
|
|
9539
9750
|
position_type: options?.positionType
|
|
9540
9751
|
});
|
|
9541
9752
|
const symbolInfo = useSymbolsInfo()[position.symbol]();
|
|
@@ -10187,254 +10398,6 @@ var useStorageLedgerAddress = () => {
|
|
|
10187
10398
|
ledgerWallet
|
|
10188
10399
|
};
|
|
10189
10400
|
};
|
|
10190
|
-
|
|
10191
|
-
// src/orderly/usePrivateDataObserver.ts
|
|
10192
|
-
var usePrivateDataObserver = (options) => {
|
|
10193
|
-
const ws = useWS();
|
|
10194
|
-
const ee = useEventEmitter();
|
|
10195
|
-
const { state, account: account9 } = useAccount();
|
|
10196
|
-
const { setAccountInfo, restoreHolding, cleanAll } = useAppStore(
|
|
10197
|
-
(state2) => state2.actions
|
|
10198
|
-
);
|
|
10199
|
-
const statusActions = useApiStatusActions();
|
|
10200
|
-
const calculatorService = useCalculatorService();
|
|
10201
|
-
const positionsActions = usePositionActions();
|
|
10202
|
-
const { data: clientInfo } = usePrivateQuery(
|
|
10203
|
-
"/v1/client/info",
|
|
10204
|
-
{
|
|
10205
|
-
revalidateOnFocus: false
|
|
10206
|
-
}
|
|
10207
|
-
);
|
|
10208
|
-
useEffect(() => {
|
|
10209
|
-
if (clientInfo) {
|
|
10210
|
-
setAccountInfo(clientInfo);
|
|
10211
|
-
}
|
|
10212
|
-
}, [clientInfo, setAccountInfo]);
|
|
10213
|
-
const { data: positions3, isLoading: isPositionLoading } = usePrivateQuery("/v1/positions", {
|
|
10214
|
-
formatter: (data) => data,
|
|
10215
|
-
onError: (error) => {
|
|
10216
|
-
statusActions.updateApiError("positions", error.message);
|
|
10217
|
-
}
|
|
10218
|
-
// revalidateOnFocus: false,
|
|
10219
|
-
});
|
|
10220
|
-
useEffect(() => {
|
|
10221
|
-
const handler = (state2) => {
|
|
10222
|
-
if (!state2.accountId) {
|
|
10223
|
-
calculatorService.stop();
|
|
10224
|
-
cleanAll();
|
|
10225
|
-
positionsActions.clearAll();
|
|
10226
|
-
}
|
|
10227
|
-
};
|
|
10228
|
-
account9.on(EVENT_NAMES.statusChanged, handler);
|
|
10229
|
-
return () => {
|
|
10230
|
-
account9.off(EVENT_NAMES.statusChanged, handler);
|
|
10231
|
-
};
|
|
10232
|
-
}, []);
|
|
10233
|
-
useEffect(() => {
|
|
10234
|
-
if (isPositionLoading) {
|
|
10235
|
-
statusActions.updateApiLoading("positions", isPositionLoading);
|
|
10236
|
-
}
|
|
10237
|
-
}, [isPositionLoading, statusActions]);
|
|
10238
|
-
useEffect(() => {
|
|
10239
|
-
if (positions3 && Array.isArray(positions3.rows)) {
|
|
10240
|
-
calculatorService.calc("position" /* POSITION */, positions3);
|
|
10241
|
-
}
|
|
10242
|
-
}, [calculatorService, positions3]);
|
|
10243
|
-
const { data: holding } = usePrivateQuery(
|
|
10244
|
-
"/v1/client/holding",
|
|
10245
|
-
{
|
|
10246
|
-
formatter: (data) => data.holding
|
|
10247
|
-
// revalidateOnFocus: false,
|
|
10248
|
-
}
|
|
10249
|
-
);
|
|
10250
|
-
useEffect(() => {
|
|
10251
|
-
if (!account9.accountId)
|
|
10252
|
-
return;
|
|
10253
|
-
const unsubscribe = ws.privateSubscribe(
|
|
10254
|
-
{
|
|
10255
|
-
id: "balance",
|
|
10256
|
-
event: "subscribe",
|
|
10257
|
-
topic: "balance",
|
|
10258
|
-
ts: Date.now()
|
|
10259
|
-
},
|
|
10260
|
-
{
|
|
10261
|
-
onMessage: (data) => {
|
|
10262
|
-
const holding2 = data?.balances ?? {};
|
|
10263
|
-
if (holding2) {
|
|
10264
|
-
calculatorService.calc("portfolio" /* PORTFOLIO */, { holding: holding2 });
|
|
10265
|
-
}
|
|
10266
|
-
}
|
|
10267
|
-
}
|
|
10268
|
-
);
|
|
10269
|
-
return () => unsubscribe?.();
|
|
10270
|
-
}, [account9.accountId]);
|
|
10271
|
-
const isHoldingInit = useRef(false);
|
|
10272
|
-
useEffect(() => {
|
|
10273
|
-
isHoldingInit.current = false;
|
|
10274
|
-
}, [state.address]);
|
|
10275
|
-
useEffect(() => {
|
|
10276
|
-
if (!holding) {
|
|
10277
|
-
return;
|
|
10278
|
-
}
|
|
10279
|
-
if (isHoldingInit.current) {
|
|
10280
|
-
calculatorService.calc("portfolio" /* PORTFOLIO */, { holding });
|
|
10281
|
-
} else {
|
|
10282
|
-
restoreHolding(holding);
|
|
10283
|
-
}
|
|
10284
|
-
isHoldingInit.current = true;
|
|
10285
|
-
}, [holding]);
|
|
10286
|
-
const [subOrder] = useLocalStorage("orderly_subscribe_order", true);
|
|
10287
|
-
const updateOrders = (data, isAlgoOrder) => {
|
|
10288
|
-
const keysMap = options.getKeysMap("orders");
|
|
10289
|
-
const filteredKeys = /* @__PURE__ */ new Map();
|
|
10290
|
-
const keyStartWith = isAlgoOrder ? "algoOrders" : "orders";
|
|
10291
|
-
const keys = keysMap.keys();
|
|
10292
|
-
for (const key of keys) {
|
|
10293
|
-
if (key.startsWith(keyStartWith)) {
|
|
10294
|
-
filteredKeys.set(key, keysMap.get(key));
|
|
10295
|
-
}
|
|
10296
|
-
}
|
|
10297
|
-
let fieldChanges = {};
|
|
10298
|
-
filteredKeys.forEach((getKey, key) => {
|
|
10299
|
-
mutate(
|
|
10300
|
-
unstable_serialize((index, prevData) => [
|
|
10301
|
-
getKey(index, prevData),
|
|
10302
|
-
state.accountId
|
|
10303
|
-
]),
|
|
10304
|
-
(prevData) => {
|
|
10305
|
-
try {
|
|
10306
|
-
if (isAlgoOrder) {
|
|
10307
|
-
const res = updateAlgoOrdersHandler(
|
|
10308
|
-
key,
|
|
10309
|
-
data,
|
|
10310
|
-
prevData
|
|
10311
|
-
);
|
|
10312
|
-
fieldChanges = res?.fieldChanges || {};
|
|
10313
|
-
return res?.mergedOrders;
|
|
10314
|
-
}
|
|
10315
|
-
return updateOrdersHandler(key, data, prevData);
|
|
10316
|
-
} catch (error) {
|
|
10317
|
-
return prevData;
|
|
10318
|
-
}
|
|
10319
|
-
},
|
|
10320
|
-
{
|
|
10321
|
-
revalidate: false
|
|
10322
|
-
}
|
|
10323
|
-
);
|
|
10324
|
-
});
|
|
10325
|
-
const formattedData = isAlgoOrder ? AlgoOrderMergeHandler.groupOrders(data) : object2underscore(data);
|
|
10326
|
-
ee.emit("orders:changed", {
|
|
10327
|
-
...formattedData,
|
|
10328
|
-
status: isAlgoOrder ? formattedData.algo_status : data.status,
|
|
10329
|
-
// custom field name
|
|
10330
|
-
fieldChanges
|
|
10331
|
-
});
|
|
10332
|
-
};
|
|
10333
|
-
useEffect(() => {
|
|
10334
|
-
if (!state.accountId) {
|
|
10335
|
-
return;
|
|
10336
|
-
}
|
|
10337
|
-
if (subOrder !== true) {
|
|
10338
|
-
return;
|
|
10339
|
-
}
|
|
10340
|
-
const unsubscribe = ws.privateSubscribe("executionreport", {
|
|
10341
|
-
onMessage: (data) => {
|
|
10342
|
-
updateOrders(data, false);
|
|
10343
|
-
}
|
|
10344
|
-
});
|
|
10345
|
-
return () => unsubscribe?.();
|
|
10346
|
-
}, [state.accountId, subOrder]);
|
|
10347
|
-
useEffect(() => {
|
|
10348
|
-
if (!state.accountId)
|
|
10349
|
-
return;
|
|
10350
|
-
if (subOrder !== true)
|
|
10351
|
-
return;
|
|
10352
|
-
const unsubscribe = ws.privateSubscribe("algoexecutionreport", {
|
|
10353
|
-
onMessage: (data) => {
|
|
10354
|
-
updateOrders(data, true);
|
|
10355
|
-
}
|
|
10356
|
-
});
|
|
10357
|
-
return () => unsubscribe?.();
|
|
10358
|
-
}, [state.accountId, subOrder]);
|
|
10359
|
-
useEffect(() => {
|
|
10360
|
-
if (!state.accountId)
|
|
10361
|
-
return;
|
|
10362
|
-
const key = ["/v1/positions", state.accountId];
|
|
10363
|
-
const unsubscribe = ws.privateSubscribe("account", {
|
|
10364
|
-
onMessage: (data) => {
|
|
10365
|
-
const { symbol, leverage } = data?.accountDetail?.symbolLeverage || {};
|
|
10366
|
-
if (symbol && leverage) {
|
|
10367
|
-
mutate(
|
|
10368
|
-
key,
|
|
10369
|
-
(prevPositions) => {
|
|
10370
|
-
if (prevPositions?.rows?.length) {
|
|
10371
|
-
return {
|
|
10372
|
-
...prevPositions,
|
|
10373
|
-
rows: prevPositions.rows.map((row) => {
|
|
10374
|
-
return row.symbol === symbol ? { ...row, leverage } : row;
|
|
10375
|
-
})
|
|
10376
|
-
};
|
|
10377
|
-
}
|
|
10378
|
-
return prevPositions;
|
|
10379
|
-
},
|
|
10380
|
-
{
|
|
10381
|
-
revalidate: false
|
|
10382
|
-
}
|
|
10383
|
-
);
|
|
10384
|
-
}
|
|
10385
|
-
}
|
|
10386
|
-
});
|
|
10387
|
-
return () => unsubscribe?.();
|
|
10388
|
-
}, [state.accountId]);
|
|
10389
|
-
useEffect(() => {
|
|
10390
|
-
if (!state.accountId) {
|
|
10391
|
-
return;
|
|
10392
|
-
}
|
|
10393
|
-
const key = ["/v1/positions", state.accountId];
|
|
10394
|
-
const unsubscribe = ws.privateSubscribe("position", {
|
|
10395
|
-
onMessage: (data) => {
|
|
10396
|
-
const { positions: nextPositions } = data;
|
|
10397
|
-
mutate(
|
|
10398
|
-
key,
|
|
10399
|
-
(prevPositions) => {
|
|
10400
|
-
if (!!prevPositions) {
|
|
10401
|
-
const newPositions = {
|
|
10402
|
-
...prevPositions,
|
|
10403
|
-
rows: prevPositions.rows.map((row) => {
|
|
10404
|
-
const itemIndex = nextPositions.findIndex(
|
|
10405
|
-
(item) => item.symbol === row.symbol
|
|
10406
|
-
);
|
|
10407
|
-
if (itemIndex >= 0) {
|
|
10408
|
-
const itemArr = nextPositions.splice(itemIndex, 1);
|
|
10409
|
-
const item = itemArr[0];
|
|
10410
|
-
if (item.averageOpenPrice === 0 && item.positionQty !== 0) {
|
|
10411
|
-
return row;
|
|
10412
|
-
}
|
|
10413
|
-
return object2underscore(item);
|
|
10414
|
-
}
|
|
10415
|
-
return row;
|
|
10416
|
-
})
|
|
10417
|
-
};
|
|
10418
|
-
if (nextPositions.length > 0) {
|
|
10419
|
-
newPositions.rows = [
|
|
10420
|
-
...newPositions.rows,
|
|
10421
|
-
...nextPositions.map(object2underscore)
|
|
10422
|
-
];
|
|
10423
|
-
}
|
|
10424
|
-
return newPositions;
|
|
10425
|
-
}
|
|
10426
|
-
},
|
|
10427
|
-
{
|
|
10428
|
-
revalidate: false
|
|
10429
|
-
}
|
|
10430
|
-
);
|
|
10431
|
-
}
|
|
10432
|
-
});
|
|
10433
|
-
return () => {
|
|
10434
|
-
unsubscribe?.();
|
|
10435
|
-
};
|
|
10436
|
-
}, [state.accountId]);
|
|
10437
|
-
};
|
|
10438
10401
|
var useMarketStore = create(
|
|
10439
10402
|
(set, get3) => ({
|
|
10440
10403
|
market: [],
|
|
@@ -18048,6 +18011,6 @@ var usePositionClose = (options) => {
|
|
|
18048
18011
|
};
|
|
18049
18012
|
};
|
|
18050
18013
|
|
|
18051
|
-
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, useAccount, useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, useOrderlyContext, usePortfolio, usePositionActions, usePositionClose, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useRwaSymbolsInfo, useRwaSymbolsInfoStore, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSymbolInfo, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTickerStream, useTokenInfo, useTokensInfo, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useVaultsHistory, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
|
|
18014
|
+
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, useAccount, useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateBySymbol, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, useOrderlyContext, usePortfolio, usePositionActions, usePositionClose, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useRwaSymbolsInfo, useRwaSymbolsInfoStore, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSymbolInfo, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTickerStream, useTokenInfo, useTokensInfo, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useVaultsHistory, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
|
|
18052
18015
|
//# sourceMappingURL=out.js.map
|
|
18053
18016
|
//# sourceMappingURL=index.mjs.map
|