@yuants/vendor-okx 0.23.22 → 0.23.24
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/account.js +2 -1
- package/dist/account.js.map +1 -1
- package/dist/api-service.js +29 -0
- package/dist/api-service.js.map +1 -0
- package/dist/api.js +15 -122
- package/dist/api.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interest_rate.js +4 -4
- package/dist/interest_rate.js.map +1 -1
- package/dist/legacy_index.js +3 -2
- package/dist/legacy_index.js.map +1 -1
- package/dist/ohlc.js +3 -3
- package/dist/ohlc.js.map +1 -1
- package/dist/product.js +4 -4
- package/dist/product.js.map +1 -1
- package/dist/public-api.js +146 -0
- package/dist/public-api.js.map +1 -0
- package/dist/quote.js +80 -11
- package/dist/quote.js.map +1 -1
- package/lib/account.d.ts.map +1 -1
- package/lib/account.js +2 -1
- package/lib/account.js.map +1 -1
- package/lib/api-service.d.ts +2 -0
- package/lib/api-service.d.ts.map +1 -0
- package/lib/api-service.js +31 -0
- package/lib/api-service.js.map +1 -0
- package/lib/api.d.ts +27 -322
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +14 -124
- package/lib/api.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/interest_rate.js +4 -4
- package/lib/interest_rate.js.map +1 -1
- package/lib/legacy_index.js +3 -2
- package/lib/legacy_index.js.map +1 -1
- package/lib/ohlc.js +3 -3
- package/lib/ohlc.js.map +1 -1
- package/lib/product.js +4 -4
- package/lib/product.js.map +1 -1
- package/lib/public-api.d.ts +359 -0
- package/lib/public-api.d.ts.map +1 -0
- package/lib/public-api.js +161 -0
- package/lib/public-api.js.map +1 -0
- package/lib/quote.d.ts.map +1 -1
- package/lib/quote.js +78 -9
- package/lib/quote.js.map +1 -1
- package/package.json +14 -14
- package/temp/package-deps.json +26 -24
package/dist/quote.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { Terminal } from '@yuants/protocol';
|
|
2
2
|
import { writeToSQL } from '@yuants/sql';
|
|
3
|
-
import { decodePath, encodePath, listWatch } from '@yuants/utils';
|
|
4
|
-
import { catchError, defer, EMPTY, filter, from, groupBy, map, merge, mergeMap, repeat, retry, scan, share, shareReplay, tap, toArray, } from 'rxjs';
|
|
5
|
-
import {
|
|
3
|
+
import { decodePath, encodePath, formatTime, listWatch } from '@yuants/utils';
|
|
4
|
+
import { catchError, concatMap, defer, distinctUntilChanged, EMPTY, filter, first, firstValueFrom, from, groupBy, map, merge, mergeMap, reduce, repeat, retry, scan, share, shareReplay, switchMap, tap, toArray, } from 'rxjs';
|
|
5
|
+
import { getInstruments, getMarketTickers, getOpenInterest } from './public-api';
|
|
6
6
|
import { useOpenInterest, useTicker } from './ws';
|
|
7
7
|
// import { useOpenInterest, useTicker } from './websocket';
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const terminal = Terminal.fromNodeEnv();
|
|
9
|
+
const swapInstruments$ = defer(() => getInstruments({ instType: 'SWAP' })).pipe(repeat({ delay: 3600000 }), retry({ delay: 10000 }), map((x) => x.data), shareReplay(1));
|
|
10
|
+
const spotInstruments$ = defer(() => getInstruments({ instType: 'SPOT' })).pipe(repeat({ delay: 3600000 }), retry({ delay: 10000 }), map((x) => x.data), shareReplay(1));
|
|
11
|
+
const shallowEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
12
|
+
const spotInstIds$ = spotInstruments$.pipe(map((items) => items.map((item) => item.instId)), distinctUntilChanged(shallowEqual), shareReplay(1));
|
|
13
|
+
const spotTickers$ = defer(() => getMarketTickers({ instType: 'SPOT' })).pipe(repeat({ delay: 5000 }), retry({ delay: 5000 }), shareReplay(1));
|
|
11
14
|
// depend by SubmitOrders
|
|
12
15
|
export const spotMarketTickers$ = defer(() => spotTickers$).pipe(mergeMap((x) => from(x.data).pipe(map((x) => [x.instId, x]), toArray(), map((x) => Object.fromEntries(x)))), repeat({ delay: 5000 }), retry({ delay: 5000 }), shareReplay(1));
|
|
13
16
|
const spotTicker$ = spotInstruments$.pipe(tap((x) => {
|
|
14
17
|
console.info('SPOT INSTRUMENTS', x.length);
|
|
15
18
|
}), listWatch((x) => x.instId, (x) => useTicker(x.instId), () => true), share());
|
|
16
|
-
const quoteOfSwapFromRest$ = defer(() =>
|
|
19
|
+
const quoteOfSwapFromRest$ = defer(() => getMarketTickers({ instType: 'SWAP' })).pipe(mergeMap((x) => x.data || []), map((x) => ({
|
|
17
20
|
datasource_id: 'OKX',
|
|
18
21
|
product_id: encodePath(x.instType, x.instId),
|
|
19
22
|
last_price: x.last,
|
|
@@ -22,7 +25,7 @@ const quoteOfSwapFromRest$ = defer(() => client.getMarketTickers({ instType: 'SW
|
|
|
22
25
|
ask_volume: x.askSz,
|
|
23
26
|
bid_volume: x.bidSz,
|
|
24
27
|
})), repeat({ delay: 1000 }), retry({ delay: 1000 }));
|
|
25
|
-
const quoteOfSpotAndMarginFromRest$ = defer(() =>
|
|
28
|
+
const quoteOfSpotAndMarginFromRest$ = defer(() => getMarketTickers({ instType: 'SPOT' })).pipe(mergeMap((x) => x.data || []), mergeMap((x) => [
|
|
26
29
|
{
|
|
27
30
|
datasource_id: 'OKX',
|
|
28
31
|
product_id: encodePath('SPOT', x.instId),
|
|
@@ -71,18 +74,84 @@ const quoteOfSpotAndMarginFromWs$ = spotTicker$.pipe(mergeMap((ticker) => [
|
|
|
71
74
|
bid_volume: ticker[0].bidSz,
|
|
72
75
|
},
|
|
73
76
|
]));
|
|
74
|
-
const swapOpenInterests$ = defer(() =>
|
|
77
|
+
const swapOpenInterests$ = defer(() => getOpenInterest({ instType: 'SWAP' })).pipe(repeat({ delay: 10000 }), retry({ delay: 10000 }), shareReplay(1));
|
|
75
78
|
const interestRateOfSwapFromWS$ = swapInstruments$.pipe(listWatch((x) => x.instId, (x) => useOpenInterest(x.instId), () => true), map((x) => ({
|
|
76
79
|
datasource_id: 'OKX',
|
|
77
80
|
product_id: encodePath('SWAP', x[0].instId),
|
|
78
81
|
open_interest: x[0].oi,
|
|
79
82
|
})), share());
|
|
83
|
+
const marginPositionTiersMap$ = defer(() => spotInstIds$.pipe(first(), map((instIds) => instIds.filter((id) => id.endsWith('USDT') || id.endsWith('USDC'))), switchMap((instIds) => {
|
|
84
|
+
const total = instIds.length;
|
|
85
|
+
let processed = 0;
|
|
86
|
+
return from(instIds).pipe(concatMap((instId) => defer(async () => {
|
|
87
|
+
const tiers = await terminal.client.requestForResponseData('OKX/PositionTiers', {
|
|
88
|
+
instType: 'MARGIN',
|
|
89
|
+
tdMode: 'cross',
|
|
90
|
+
instId,
|
|
91
|
+
});
|
|
92
|
+
if (!(tiers === null || tiers === void 0 ? void 0 : tiers.data)) {
|
|
93
|
+
throw new Error(`Failed to load position tiers for ${instId}: ${tiers.msg}`);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
instId,
|
|
97
|
+
tiers,
|
|
98
|
+
};
|
|
99
|
+
}).pipe(retry({ delay: 2000 }))), reduce((map, { instId, tiers }) => {
|
|
100
|
+
processed += 1;
|
|
101
|
+
console.info(formatTime(Date.now()), `Loaded margin position tiers ${processed}/${total} (${instId})`);
|
|
102
|
+
if (tiers === null || tiers === void 0 ? void 0 : tiers.data) {
|
|
103
|
+
map.set(instId, tiers.data);
|
|
104
|
+
}
|
|
105
|
+
return map;
|
|
106
|
+
}, new Map()));
|
|
107
|
+
}))).pipe(
|
|
108
|
+
//
|
|
109
|
+
retry({ delay: 60000 }), repeat({ delay: 86400000 }), shareReplay(1));
|
|
110
|
+
// Margin 的 open interest 只依赖 position-tier:
|
|
111
|
+
// 1) 启动时先拉全量 MARGIN 仓位档位并缓存,下次直接命中;
|
|
112
|
+
// 2) 档位内只保留同 tier 杠杆最高的记录;
|
|
113
|
+
// 3) 当前策略只使用 tier=1 的 quoteMaxLoan 作为持仓上限,不再混合 /account/max-size;
|
|
114
|
+
// 4) 每个 instId 60 秒刷新一次,并在接口报错时 10 秒重试。
|
|
115
|
+
const marginOpenInterest$ = spotInstIds$.pipe(mergeMap((instIds) => from(instIds).pipe(mergeMap((instId) => defer(async () => {
|
|
116
|
+
var _a;
|
|
117
|
+
const tiersMap = await firstValueFrom(marginPositionTiersMap$);
|
|
118
|
+
const tiers = tiersMap.get(instId);
|
|
119
|
+
if (!(tiers === null || tiers === void 0 ? void 0 : tiers.length)) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
const tierByLevel = tiers
|
|
123
|
+
.filter((tier) => !tier.instId || tier.instId === instId)
|
|
124
|
+
.reduce((mapTierToTierInfo, tierInfo) => {
|
|
125
|
+
const existing = mapTierToTierInfo.get(tierInfo.tier);
|
|
126
|
+
if (!existing || +tierInfo.maxLever > +existing.maxLever) {
|
|
127
|
+
mapTierToTierInfo.set(tierInfo.tier, tierInfo);
|
|
128
|
+
}
|
|
129
|
+
return mapTierToTierInfo;
|
|
130
|
+
}, new Map());
|
|
131
|
+
// 获取一级杠杆的最大可借贷额度作为持仓量
|
|
132
|
+
const openInterest = +(((_a = tierByLevel.get('1')) === null || _a === void 0 ? void 0 : _a.quoteMaxLoan) || 0);
|
|
133
|
+
return {
|
|
134
|
+
instId,
|
|
135
|
+
openInterest,
|
|
136
|
+
};
|
|
137
|
+
}).pipe(retry({ delay: 10000 }), repeat({ delay: 60000 }))))), filter((result) => result !== null), map(({ instId, openInterest }) => {
|
|
138
|
+
const partial = {
|
|
139
|
+
datasource_id: 'OKX',
|
|
140
|
+
product_id: encodePath('MARGIN', instId),
|
|
141
|
+
};
|
|
142
|
+
if (typeof openInterest === 'number' && Number.isFinite(openInterest)) {
|
|
143
|
+
partial.open_interest = `${openInterest}`;
|
|
144
|
+
}
|
|
145
|
+
return partial;
|
|
146
|
+
}), share());
|
|
147
|
+
marginOpenInterest$.subscribe();
|
|
80
148
|
const quoteSources$ = [
|
|
81
149
|
quoteOfSwapFromWs$,
|
|
82
150
|
interestRateOfSwapFromWS$,
|
|
83
151
|
quoteOfSwapFromRest$,
|
|
84
152
|
quoteOfSpotAndMarginFromWs$,
|
|
85
153
|
quoteOfSpotAndMarginFromRest$,
|
|
154
|
+
marginOpenInterest$,
|
|
86
155
|
];
|
|
87
156
|
const quote$ = defer(() => merge(...quoteSources$.map((x$) => defer(() => x$).pipe(
|
|
88
157
|
// 防止单个流关闭导致整体关闭
|
|
@@ -93,7 +162,7 @@ catchError(() => EMPTY))))).pipe(groupBy((x) => encodePath(x.datasource_id, x.pr
|
|
|
93
162
|
}), share());
|
|
94
163
|
// 合并不同来源的数据并进行合并,避免死锁
|
|
95
164
|
if (process.env.WRITE_QUOTE_TO_SQL === 'true') {
|
|
96
|
-
|
|
165
|
+
terminal.channel.publishChannel('quote', { pattern: `^OKX/` }, (channel_id) => {
|
|
97
166
|
const [datasource_id, product_id] = decodePath(channel_id);
|
|
98
167
|
if (!datasource_id) {
|
|
99
168
|
throw 'datasource_id is required';
|
|
@@ -105,7 +174,7 @@ if (process.env.WRITE_QUOTE_TO_SQL === 'true') {
|
|
|
105
174
|
});
|
|
106
175
|
quote$
|
|
107
176
|
.pipe(writeToSQL({
|
|
108
|
-
terminal
|
|
177
|
+
terminal,
|
|
109
178
|
writeInterval: 1000,
|
|
110
179
|
tableName: 'quote',
|
|
111
180
|
conflictKeys: ['datasource_id', 'product_id'],
|
package/dist/quote.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,UAAU,EACV,KAAK,EACL,KAAK,EACL,MAAM,EACN,IAAI,EACJ,OAAO,EACP,GAAG,EACH,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAK,EACL,IAAI,EACJ,KAAK,EACL,WAAW,EACX,GAAG,EACH,OAAO,GACR,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAClD,4DAA4D;AAE5D,MAAM,gBAAgB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CACpF,MAAM,CAAC,EAAE,KAAK,EAAE,OAAQ,EAAE,CAAC,EAC3B,KAAK,CAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAClB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AACF,MAAM,gBAAgB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CACpF,MAAM,CAAC,EAAE,KAAK,EAAE,OAAQ,EAAE,CAAC,EAC3B,KAAK,CAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACxB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAClB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAClF,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACvB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,yBAAyB;AACzB,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAC9D,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CACb,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAU,CAAC,EAClC,OAAO,EAAE,EACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAClC,CACF,EACD,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACvB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CACvC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;IACR,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC,CAAC,EACF,SAAS,CACP,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EACf,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAC1B,GAAG,EAAE,CAAC,IAAI,CACX,EACD,KAAK,EAAE,CACR,CAAC;AAEF,MAAM,oBAAoB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAC1F,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAC7B,GAAG,CACD,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC;IACvB,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;IAC5C,UAAU,EAAE,CAAC,CAAC,IAAI;IAClB,SAAS,EAAE,CAAC,CAAC,KAAK;IAClB,SAAS,EAAE,CAAC,CAAC,KAAK;IAClB,UAAU,EAAE,CAAC,CAAC,KAAK;IACnB,UAAU,EAAE,CAAC,CAAC,KAAK;CACpB,CAAC,CACH,EACD,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACvB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CACvB,CAAC;AAEF,MAAM,6BAA6B,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CACnG,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAC7B,QAAQ,CAAC,CAAC,CAAC,EAAqB,EAAE,CAAC;IACjC;QACE,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACxC,UAAU,EAAE,CAAC,CAAC,IAAI;QAClB,SAAS,EAAE,CAAC,CAAC,KAAK;QAClB,SAAS,EAAE,CAAC,CAAC,KAAK;QAClB,UAAU,EAAE,CAAC,CAAC,KAAK;QACnB,UAAU,EAAE,CAAC,CAAC,KAAK;KACpB;IACD;QACE,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QAC1C,UAAU,EAAE,CAAC,CAAC,IAAI;QAClB,SAAS,EAAE,CAAC,CAAC,KAAK;QAClB,SAAS,EAAE,CAAC,CAAC,KAAK;QAClB,UAAU,EAAE,CAAC,CAAC,KAAK;QACnB,UAAU,EAAE,CAAC,CAAC,KAAK;KACpB;CACF,CAAC,EACF,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACvB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CACvB,CAAC;AAEF,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,IAAI,CAC9C,SAAS,CACP,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EACf,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAC1B,GAAG,EAAE,CAAC,IAAI,CACX,EACD,GAAG,CACD,CAAC,MAAM,EAAmB,EAAE,CAAC,CAAC;IAC5B,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;IAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;IAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;IAC1B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;IAC3B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;CAC5B,CAAC,CACH,CACF,CAAC;AAEF,MAAM,2BAA2B,GAAG,WAAW,CAAC,IAAI,CAClD,QAAQ,CAAC,CAAC,MAAM,EAAqB,EAAE,CAAC;IACtC;QACE,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAChD,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;QAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC1B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC3B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;KAC5B;IACD;QACE,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAClD,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;QAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC1B,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC1B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;QAC3B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;KAC5B;CACF,CAAC,CACH,CAAC;AAEF,MAAM,kBAAkB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CACvF,MAAM,CAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACzB,KAAK,CAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACxB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,yBAAyB,GAAG,gBAAgB,CAAC,IAAI,CACrD,SAAS,CACP,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EACf,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,EAChC,GAAG,EAAE,CAAC,IAAI,CACX,EACD,GAAG,CACD,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC;IACvB,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;CACvB,CAAC,CACH,EACD,KAAK,EAAE,CACR,CAAC;AAEF,MAAM,aAAa,GAAG;IACpB,kBAAkB;IAClB,yBAAyB;IACzB,oBAAoB;IACpB,2BAA2B;IAC3B,6BAA6B;CAC9B,CAAC;AAEF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,CACxB,KAAK,CACH,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAC1B,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI;AAClB,gBAAgB;AAChB,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CACxB,CACF,CACF,CACF,CAAC,IAAI,CACJ,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,EACzD,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE;IAClB,OAAO,MAAM,CAAC,IAAI;IAChB,EAAE;IACF,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAqB,CAAC,CACnE,CAAC;AACJ,CAAC,CAAC,EACF,KAAK,EAAE,CACR,CAAC;AAEF,sBAAsB;AACtB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,EAAE;IAC7C,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,EAAE,EAAE;QAC1F,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QAC3D,IAAI,CAAC,aAAa,EAAE;YAClB,MAAM,2BAA2B,CAAC;SACnC;QACD,IAAI,CAAC,UAAU,EAAE;YACf,MAAM,wBAAwB,CAAC;SAChC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,MAAM;SACH,IAAI,CACH,UAAU,CAAC;QACT,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;QAChC,aAAa,EAAE,IAAI;QACnB,SAAS,EAAE,OAAO;QAClB,YAAY,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC;KAC9C,CAAC,CACH;SACA,SAAS,EAAE,CAAC;CAChB;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,IAAI,CACnE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAU,CAAC,CAAC,CAAC,EACvE,WAAW,CAAC,CAAC,CAAC,CACf,CAAC","sourcesContent":["import { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { writeToSQL } from '@yuants/sql';\nimport { decodePath, encodePath, listWatch } from '@yuants/utils';\nimport {\n catchError,\n defer,\n EMPTY,\n filter,\n from,\n groupBy,\n map,\n merge,\n mergeMap,\n repeat,\n retry,\n scan,\n share,\n shareReplay,\n tap,\n toArray,\n} from 'rxjs';\nimport { client } from './api';\nimport { useOpenInterest, useTicker } from './ws';\n// import { useOpenInterest, useTicker } from './websocket';\n\nconst swapInstruments$ = defer(() => client.getInstruments({ instType: 'SWAP' })).pipe(\n repeat({ delay: 3600_000 }),\n retry({ delay: 10_000 }),\n map((x) => x.data),\n shareReplay(1),\n);\nconst spotInstruments$ = defer(() => client.getInstruments({ instType: 'SPOT' })).pipe(\n repeat({ delay: 3600_000 }),\n retry({ delay: 10_000 }),\n map((x) => x.data),\n shareReplay(1),\n);\n\nconst spotTickers$ = defer(() => client.getMarketTickers({ instType: 'SPOT' })).pipe(\n repeat({ delay: 5000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\n// depend by SubmitOrders\nexport const spotMarketTickers$ = defer(() => spotTickers$).pipe(\n mergeMap((x) =>\n from(x.data).pipe(\n map((x) => [x.instId, x] as const),\n toArray(),\n map((x) => Object.fromEntries(x)),\n ),\n ),\n repeat({ delay: 5000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nconst spotTicker$ = spotInstruments$.pipe(\n tap((x) => {\n console.info('SPOT INSTRUMENTS', x.length);\n }),\n listWatch(\n (x) => x.instId,\n (x) => useTicker(x.instId),\n () => true,\n ),\n share(),\n);\n\nconst quoteOfSwapFromRest$ = defer(() => client.getMarketTickers({ instType: 'SWAP' })).pipe(\n mergeMap((x) => x.data || []),\n map(\n (x): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath(x.instType, x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n }),\n ),\n repeat({ delay: 1000 }),\n retry({ delay: 1000 }),\n);\n\nconst quoteOfSpotAndMarginFromRest$ = defer(() => client.getMarketTickers({ instType: 'SPOT' })).pipe(\n mergeMap((x) => x.data || []),\n mergeMap((x): Partial<IQuote>[] => [\n {\n datasource_id: 'OKX',\n product_id: encodePath('SPOT', x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n },\n {\n datasource_id: 'OKX',\n product_id: encodePath('MARGIN', x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n },\n ]),\n repeat({ delay: 1000 }),\n retry({ delay: 1000 }),\n);\n\nconst quoteOfSwapFromWs$ = swapInstruments$.pipe(\n listWatch(\n (x) => x.instId,\n (x) => useTicker(x.instId),\n () => true,\n ),\n map(\n (ticker): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath('SWAP', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n }),\n ),\n);\n\nconst quoteOfSpotAndMarginFromWs$ = spotTicker$.pipe(\n mergeMap((ticker): Partial<IQuote>[] => [\n {\n datasource_id: 'OKX',\n product_id: encodePath('SPOT', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n },\n {\n datasource_id: 'OKX',\n product_id: encodePath('MARGIN', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n },\n ]),\n);\n\nconst swapOpenInterests$ = defer(() => client.getOpenInterest({ instType: 'SWAP' })).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nconst interestRateOfSwapFromWS$ = swapInstruments$.pipe(\n listWatch(\n (x) => x.instId,\n (x) => useOpenInterest(x.instId),\n () => true,\n ),\n map(\n (x): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath('SWAP', x[0].instId),\n open_interest: x[0].oi,\n }),\n ),\n share(),\n);\n\nconst quoteSources$ = [\n quoteOfSwapFromWs$,\n interestRateOfSwapFromWS$,\n quoteOfSwapFromRest$,\n quoteOfSpotAndMarginFromWs$,\n quoteOfSpotAndMarginFromRest$,\n];\n\nconst quote$ = defer(() =>\n merge(\n ...quoteSources$.map((x$) =>\n defer(() => x$).pipe(\n // 防止单个流关闭导致整体关闭\n catchError(() => EMPTY),\n ),\n ),\n ),\n).pipe(\n groupBy((x) => encodePath(x.datasource_id, x.product_id)),\n mergeMap((group$) => {\n return group$.pipe(\n //\n scan((acc, cur) => Object.assign(acc, cur), {} as Partial<IQuote>),\n );\n }),\n share(),\n);\n\n// 合并不同来源的数据并进行合并,避免死锁\nif (process.env.WRITE_QUOTE_TO_SQL === 'true') {\n Terminal.fromNodeEnv().channel.publishChannel('quote', { pattern: `^OKX/` }, (channel_id) => {\n const [datasource_id, product_id] = decodePath(channel_id);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n return quote$.pipe(filter((x) => x.product_id === product_id));\n });\n\n quote$\n .pipe(\n writeToSQL({\n terminal: Terminal.fromNodeEnv(),\n writeInterval: 1000,\n tableName: 'quote',\n conflictKeys: ['datasource_id', 'product_id'],\n }),\n )\n .subscribe();\n}\n\nexport const swapOpenInterest$ = defer(() => swapOpenInterests$).pipe(\n map((x) => new Map(x.data.map((x: any) => [x.instId, +x.oi] as const))),\n shareReplay(1),\n);\n"]}
|
|
1
|
+
{"version":3,"file":"quote.js","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":"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","sourcesContent":["import { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { writeToSQL } from '@yuants/sql';\nimport { decodePath, encodePath, formatTime, listWatch } from '@yuants/utils';\nimport {\n catchError,\n concatMap,\n defer,\n distinctUntilChanged,\n EMPTY,\n filter,\n first,\n firstValueFrom,\n from,\n groupBy,\n map,\n merge,\n mergeMap,\n reduce,\n repeat,\n retry,\n scan,\n share,\n shareReplay,\n switchMap,\n tap,\n toArray,\n} from 'rxjs';\nimport { getInstruments, getMarketTickers, getOpenInterest, getPositionTiers } from './public-api';\nimport { useOpenInterest, useTicker } from './ws';\n// import { useOpenInterest, useTicker } from './websocket';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst swapInstruments$ = defer(() => getInstruments({ instType: 'SWAP' })).pipe(\n repeat({ delay: 3600_000 }),\n retry({ delay: 10_000 }),\n map((x) => x.data),\n shareReplay(1),\n);\nconst spotInstruments$ = defer(() => getInstruments({ instType: 'SPOT' })).pipe(\n repeat({ delay: 3600_000 }),\n retry({ delay: 10_000 }),\n map((x) => x.data),\n shareReplay(1),\n);\n\nconst shallowEqual = (a: string[], b: string[]) => a.length === b.length && a.every((v, i) => v === b[i]);\n\nconst spotInstIds$ = spotInstruments$.pipe(\n map((items) => items.map((item) => item.instId)),\n distinctUntilChanged(shallowEqual),\n shareReplay(1),\n);\n\nconst spotTickers$ = defer(() => getMarketTickers({ instType: 'SPOT' })).pipe(\n repeat({ delay: 5000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\n// depend by SubmitOrders\nexport const spotMarketTickers$ = defer(() => spotTickers$).pipe(\n mergeMap((x) =>\n from(x.data).pipe(\n map((x) => [x.instId, x] as const),\n toArray(),\n map((x) => Object.fromEntries(x)),\n ),\n ),\n repeat({ delay: 5000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nconst spotTicker$ = spotInstruments$.pipe(\n tap((x) => {\n console.info('SPOT INSTRUMENTS', x.length);\n }),\n listWatch(\n (x) => x.instId,\n (x) => useTicker(x.instId),\n () => true,\n ),\n share(),\n);\n\nconst quoteOfSwapFromRest$ = defer(() => getMarketTickers({ instType: 'SWAP' })).pipe(\n mergeMap((x) => x.data || []),\n map(\n (x): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath(x.instType, x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n }),\n ),\n repeat({ delay: 1000 }),\n retry({ delay: 1000 }),\n);\n\nconst quoteOfSpotAndMarginFromRest$ = defer(() => getMarketTickers({ instType: 'SPOT' })).pipe(\n mergeMap((x) => x.data || []),\n mergeMap((x): Partial<IQuote>[] => [\n {\n datasource_id: 'OKX',\n product_id: encodePath('SPOT', x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n },\n {\n datasource_id: 'OKX',\n product_id: encodePath('MARGIN', x.instId),\n last_price: x.last,\n ask_price: x.askPx,\n bid_price: x.bidPx,\n ask_volume: x.askSz,\n bid_volume: x.bidSz,\n },\n ]),\n repeat({ delay: 1000 }),\n retry({ delay: 1000 }),\n);\n\nconst quoteOfSwapFromWs$ = swapInstruments$.pipe(\n listWatch(\n (x) => x.instId,\n (x) => useTicker(x.instId),\n () => true,\n ),\n map(\n (ticker): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath('SWAP', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n }),\n ),\n);\n\nconst quoteOfSpotAndMarginFromWs$ = spotTicker$.pipe(\n mergeMap((ticker): Partial<IQuote>[] => [\n {\n datasource_id: 'OKX',\n product_id: encodePath('SPOT', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n },\n {\n datasource_id: 'OKX',\n product_id: encodePath('MARGIN', ticker[0].instId),\n last_price: ticker[0].last,\n ask_price: ticker[0].askPx,\n bid_price: ticker[0].bidPx,\n ask_volume: ticker[0].askSz,\n bid_volume: ticker[0].bidSz,\n },\n ]),\n);\n\nconst swapOpenInterests$ = defer(() => getOpenInterest({ instType: 'SWAP' })).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nconst interestRateOfSwapFromWS$ = swapInstruments$.pipe(\n listWatch(\n (x) => x.instId,\n (x) => useOpenInterest(x.instId),\n () => true,\n ),\n map(\n (x): Partial<IQuote> => ({\n datasource_id: 'OKX',\n product_id: encodePath('SWAP', x[0].instId),\n open_interest: x[0].oi,\n }),\n ),\n share(),\n);\n\ntype PositionTiersResponse = Awaited<ReturnType<typeof getPositionTiers>>;\ntype PositionTiersEntry = PositionTiersResponse['data'];\n\nconst marginPositionTiersMap$ = defer(() =>\n spotInstIds$.pipe(\n first(),\n map((instIds) => instIds.filter((id) => id.endsWith('USDT') || id.endsWith('USDC'))),\n switchMap((instIds) => {\n const total = instIds.length;\n let processed = 0;\n return from(instIds).pipe(\n concatMap((instId) =>\n defer(async () => {\n const tiers = await terminal.client.requestForResponseData<\n { instType: string; tdMode: string; instId: string },\n PositionTiersResponse\n >('OKX/PositionTiers', {\n instType: 'MARGIN',\n tdMode: 'cross',\n instId,\n });\n if (!tiers?.data) {\n throw new Error(`Failed to load position tiers for ${instId}: ${tiers.msg}`);\n }\n return {\n instId,\n tiers,\n };\n }).pipe(retry({ delay: 2000 })),\n ),\n reduce((map, { instId, tiers }) => {\n processed += 1;\n console.info(\n formatTime(Date.now()),\n `Loaded margin position tiers ${processed}/${total} (${instId})`,\n );\n if (tiers?.data) {\n map.set(instId, tiers.data);\n }\n return map;\n }, new Map<string, PositionTiersEntry>()),\n );\n }),\n ),\n).pipe(\n //\n retry({ delay: 60_000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\n// Margin 的 open interest 只依赖 position-tier:\n// 1) 启动时先拉全量 MARGIN 仓位档位并缓存,下次直接命中;\n// 2) 档位内只保留同 tier 杠杆最高的记录;\n// 3) 当前策略只使用 tier=1 的 quoteMaxLoan 作为持仓上限,不再混合 /account/max-size;\n// 4) 每个 instId 60 秒刷新一次,并在接口报错时 10 秒重试。\nconst marginOpenInterest$ = spotInstIds$.pipe(\n mergeMap((instIds) =>\n from(instIds).pipe(\n mergeMap((instId) =>\n defer(async () => {\n const tiersMap = await firstValueFrom(marginPositionTiersMap$);\n const tiers = tiersMap.get(instId);\n if (!tiers?.length) {\n return null;\n }\n\n const tierByLevel = tiers\n .filter((tier) => !tier.instId || tier.instId === instId)\n .reduce((mapTierToTierInfo, tierInfo) => {\n const existing = mapTierToTierInfo.get(tierInfo.tier);\n if (!existing || +tierInfo.maxLever > +existing.maxLever) {\n mapTierToTierInfo.set(tierInfo.tier, tierInfo);\n }\n return mapTierToTierInfo;\n }, new Map<string, (typeof tiers)[number]>());\n // 获取一级杠杆的最大可借贷额度作为持仓量\n const openInterest = +(tierByLevel.get('1')?.quoteMaxLoan || 0);\n\n return {\n instId,\n openInterest,\n };\n }).pipe(retry({ delay: 10_000 }), repeat({ delay: 60_000 })),\n ),\n ),\n ),\n filter((result): result is { instId: string; openInterest: number } => result !== null),\n map(({ instId, openInterest }) => {\n const partial: Partial<IQuote> = {\n datasource_id: 'OKX',\n product_id: encodePath('MARGIN', instId),\n };\n if (typeof openInterest === 'number' && Number.isFinite(openInterest)) {\n partial.open_interest = `${openInterest}`;\n }\n return partial;\n }),\n share(),\n);\n\nmarginOpenInterest$.subscribe();\n\nconst quoteSources$ = [\n quoteOfSwapFromWs$,\n interestRateOfSwapFromWS$,\n quoteOfSwapFromRest$,\n quoteOfSpotAndMarginFromWs$,\n quoteOfSpotAndMarginFromRest$,\n marginOpenInterest$,\n];\n\nconst quote$ = defer(() =>\n merge(\n ...quoteSources$.map((x$) =>\n defer(() => x$).pipe(\n // 防止单个流关闭导致整体关闭\n catchError(() => EMPTY),\n ),\n ),\n ),\n).pipe(\n groupBy((x) => encodePath(x.datasource_id, x.product_id)),\n mergeMap((group$) => {\n return group$.pipe(\n //\n scan((acc, cur) => Object.assign(acc, cur), {} as Partial<IQuote>),\n );\n }),\n share(),\n);\n\n// 合并不同来源的数据并进行合并,避免死锁\nif (process.env.WRITE_QUOTE_TO_SQL === 'true') {\n terminal.channel.publishChannel('quote', { pattern: `^OKX/` }, (channel_id) => {\n const [datasource_id, product_id] = decodePath(channel_id);\n if (!datasource_id) {\n throw 'datasource_id is required';\n }\n if (!product_id) {\n throw 'product_id is required';\n }\n return quote$.pipe(filter((x) => x.product_id === product_id));\n });\n\n quote$\n .pipe(\n writeToSQL({\n terminal,\n writeInterval: 1000,\n tableName: 'quote',\n conflictKeys: ['datasource_id', 'product_id'],\n }),\n )\n .subscribe();\n}\n\nexport const swapOpenInterest$ = defer(() => swapOpenInterests$).pipe(\n map((x) => new Map(x.data.map((x: any) => [x.instId, +x.oi] as const))),\n shareReplay(1),\n);\n"]}
|
package/lib/account.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;EAI1B,CAAC;AAQF,eAAO,MAAM,WAAW,mCAIvB,CAAC;AAmDF,eAAO,MAAM,iBAAiB,mCAG7B,CAAC"}
|
package/lib/account.js
CHANGED
|
@@ -8,6 +8,7 @@ const utils_1 = require("@yuants/utils");
|
|
|
8
8
|
const rxjs_1 = require("rxjs");
|
|
9
9
|
const api_1 = require("./api");
|
|
10
10
|
const product_1 = require("./product");
|
|
11
|
+
const public_api_1 = require("./public-api");
|
|
11
12
|
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
12
13
|
exports.accountConfig$ = (0, rxjs_1.defer)(() => api_1.client.getAccountConfig()).pipe((0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 10000 }), (0, rxjs_1.shareReplay)(1));
|
|
13
14
|
const subAccountUids$ = (0, rxjs_1.defer)(() => api_1.client.getSubAccountList()).pipe((0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 10000 }), (0, rxjs_1.shareReplay)(1));
|
|
@@ -42,7 +43,7 @@ exports.accountUid$ = exports.accountConfig$.pipe((0, rxjs_1.map)((x) => x.data[
|
|
|
42
43
|
});
|
|
43
44
|
}, { auto_refresh_interval: 5000 });
|
|
44
45
|
}).subscribe();
|
|
45
|
-
const marketIndexTickerUSDT$ = (0, rxjs_1.defer)(() =>
|
|
46
|
+
const marketIndexTickerUSDT$ = (0, rxjs_1.defer)(() => (0, public_api_1.getMarketIndexTicker)({ quoteCcy: 'USDT' })).pipe((0, rxjs_1.map)((x) => {
|
|
46
47
|
const mapInstIdToPrice = new Map();
|
|
47
48
|
x.data.forEach((inst) => mapInstIdToPrice.set(inst.instId, Number(inst.idxPx)));
|
|
48
49
|
return mapInstIdToPrice;
|
package/lib/account.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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","sourcesContent":["import { addAccountMarket, IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { providePendingOrdersService } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { defer, filter, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\nimport { client } from './api';\nimport { productService } from './product';\n\nconst terminal = Terminal.fromNodeEnv();\n\nexport const accountConfig$ = defer(() => client.getAccountConfig()).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nconst subAccountUids$ = defer(() => client.getSubAccountList()).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nexport const accountUid$ = accountConfig$.pipe(\n map((x) => x.data[0].uid),\n filter((x) => !!x),\n shareReplay(1),\n);\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n const account_id = `okx/${uid}/trading`;\n providePendingOrdersService(\n terminal,\n account_id,\n async () => {\n const orders = await client.getTradeOrdersPending({});\n return orders.data.map((x) => {\n const order_type = x.ordType === 'market' ? 'MARKET' : x.ordType === 'limit' ? 'LIMIT' : 'UNKNOWN';\n\n const order_direction =\n x.side === 'buy'\n ? x.posSide === 'long'\n ? 'OPEN_LONG'\n : 'CLOSE_SHORT'\n : x.posSide === 'short'\n ? 'OPEN_SHORT'\n : 'CLOSE_LONG';\n return {\n order_id: x.ordId,\n account_id,\n product_id: encodePath(x.instType, x.instId),\n submit_at: +x.cTime,\n filled_at: +x.fillTime,\n order_type,\n order_direction,\n volume: +x.sz,\n traded_volume: +x.accFillSz,\n price: +x.px,\n traded_price: +x.avgPx,\n };\n });\n },\n { auto_refresh_interval: 5000 },\n );\n}).subscribe();\n\nconst marketIndexTickerUSDT$ = defer(() => client.getMarketIndexTicker({ quoteCcy: 'USDT' })).pipe(\n map((x) => {\n const mapInstIdToPrice = new Map<string, number>();\n x.data.forEach((inst) => mapInstIdToPrice.set(inst.instId, Number(inst.idxPx)));\n return mapInstIdToPrice;\n }),\n repeat({ delay: 1000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const tradingAccountId$ = accountUid$.pipe(\n map((uid) => `okx/${uid}/trading`),\n shareReplay(1),\n);\n\ndefer(async () => {\n const tradingAccountId = await firstValueFrom(tradingAccountId$);\n addAccountMarket(terminal, { account_id: tradingAccountId, market_id: 'OKX' });\n\n provideAccountInfoService(\n terminal,\n tradingAccountId,\n async () => {\n const [positionsApi, balanceApi, mapProductIdToProduct, marketIndexTickerUSDT] = await Promise.all([\n client.getAccountPositions({}),\n client.getAccountBalance({}),\n firstValueFrom(productService.mapProductIdToProduct$),\n firstValueFrom(marketIndexTickerUSDT$),\n ]);\n\n let totalEquity = 0;\n let totalFree = 0;\n const positions: IPosition[] = [];\n\n balanceApi.data[0]?.details.forEach((detail) => {\n if (detail.ccy === 'USDT') {\n const balance = +(detail.cashBal ?? 0);\n const free = Math.min(\n balance, // free should no more than balance if there is much profits\n +(detail.availEq ?? 0),\n );\n const equity = +(detail.eq ?? 0) - +(detail.stgyEq ?? 0);\n totalEquity += equity;\n totalFree += free;\n } else {\n const volume = +(detail.cashBal ?? 0);\n const free_volume = Math.min(\n volume, // free should no more than balance if there is much profits\n +(detail.availEq ?? 0),\n );\n const closable_price = marketIndexTickerUSDT.get(detail.ccy + '-USDT') || 0;\n const delta_equity = volume * closable_price || 0;\n const delta_profit = +detail.totalPnl || 0;\n\n const product_id = encodePath('SPOT', `${detail.ccy}-USDT`);\n positions.push({\n position_id: product_id,\n datasource_id: 'OKX',\n product_id: product_id,\n direction: 'LONG',\n volume: volume,\n free_volume: free_volume,\n position_price: +detail.accAvgPx,\n floating_profit: delta_profit,\n closable_price: closable_price,\n valuation: delta_equity,\n });\n\n totalEquity += delta_equity;\n }\n });\n positionsApi.data.forEach((x) => {\n const direction =\n x.posSide === 'long' ? 'LONG' : x.posSide === 'short' ? 'SHORT' : +x.pos > 0 ? 'LONG' : 'SHORT';\n const volume = Math.abs(+x.pos);\n const product_id = encodePath(x.instType, x.instId);\n const closable_price = +x.last;\n const valuation =\n (mapProductIdToProduct.get(product_id)?.value_scale ?? 1) * volume * closable_price || 0;\n\n positions.push({\n position_id: x.posId,\n datasource_id: 'OKX',\n product_id,\n direction,\n volume: volume,\n free_volume: +x.availPos,\n closable_price,\n position_price: +x.avgPx,\n floating_profit: +x.upl,\n valuation,\n });\n });\n return {\n money: {\n currency: 'USDT',\n equity: totalEquity,\n free: totalFree,\n },\n positions: positions,\n };\n },\n { auto_refresh_interval: 1000 },\n );\n}).subscribe();\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n\n const fundingAccountId = `okx/${uid}/funding/USDT`;\n\n provideAccountInfoService(\n terminal,\n fundingAccountId,\n async () => {\n const [assetBalances, marketIndexTickerUSDT] = await Promise.all([\n client.getAssetBalances({}),\n firstValueFrom(marketIndexTickerUSDT$),\n ]);\n\n const positions: IPosition[] = [];\n let equity = 0;\n let free = 0;\n\n assetBalances.data.forEach((x) => {\n if (x.ccy === 'USDT') {\n const balance = +x.bal;\n equity += balance;\n free += balance;\n return;\n }\n\n const price = marketIndexTickerUSDT.get(`${x.ccy}-USDT`) || 0;\n const valuation = price * +x.bal || 0;\n const productId = encodePath('SPOT', `${x.ccy}-USDT`);\n\n positions.push({\n datasource_id: 'OKX',\n position_id: productId,\n product_id: productId,\n direction: 'LONG',\n volume: +x.bal,\n free_volume: +x.bal,\n position_price: price,\n floating_profit: 0,\n closable_price: price,\n valuation,\n });\n\n equity += valuation;\n });\n\n return {\n money: {\n currency: 'USDT',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n );\n}).subscribe();\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n const earningAccountId = `okx/${uid}/earning/USDT`;\n provideAccountInfoService(\n terminal,\n earningAccountId,\n async () => {\n const offers = await client.getFinanceSavingsBalance({});\n const equity = offers.data.filter((x) => x.ccy === 'USDT').reduce((acc, x) => acc + +x.amt, 0);\n const free = equity;\n return {\n money: {\n currency: 'USDT',\n equity,\n free,\n },\n positions: [],\n };\n },\n { auto_refresh_interval: 5000 },\n );\n}).subscribe();\n"]}
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"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","sourcesContent":["import { addAccountMarket, IPosition, provideAccountInfoService } from '@yuants/data-account';\nimport { providePendingOrdersService } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { defer, filter, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\nimport { client } from './api';\nimport { productService } from './product';\nimport { getMarketIndexTicker } from './public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nexport const accountConfig$ = defer(() => client.getAccountConfig()).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nconst subAccountUids$ = defer(() => client.getSubAccountList()).pipe(\n repeat({ delay: 10_000 }),\n retry({ delay: 10_000 }),\n shareReplay(1),\n);\n\nexport const accountUid$ = accountConfig$.pipe(\n map((x) => x.data[0].uid),\n filter((x) => !!x),\n shareReplay(1),\n);\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n const account_id = `okx/${uid}/trading`;\n providePendingOrdersService(\n terminal,\n account_id,\n async () => {\n const orders = await client.getTradeOrdersPending({});\n return orders.data.map((x) => {\n const order_type = x.ordType === 'market' ? 'MARKET' : x.ordType === 'limit' ? 'LIMIT' : 'UNKNOWN';\n\n const order_direction =\n x.side === 'buy'\n ? x.posSide === 'long'\n ? 'OPEN_LONG'\n : 'CLOSE_SHORT'\n : x.posSide === 'short'\n ? 'OPEN_SHORT'\n : 'CLOSE_LONG';\n return {\n order_id: x.ordId,\n account_id,\n product_id: encodePath(x.instType, x.instId),\n submit_at: +x.cTime,\n filled_at: +x.fillTime,\n order_type,\n order_direction,\n volume: +x.sz,\n traded_volume: +x.accFillSz,\n price: +x.px,\n traded_price: +x.avgPx,\n };\n });\n },\n { auto_refresh_interval: 5000 },\n );\n}).subscribe();\n\nconst marketIndexTickerUSDT$ = defer(() => getMarketIndexTicker({ quoteCcy: 'USDT' })).pipe(\n map((x) => {\n const mapInstIdToPrice = new Map<string, number>();\n x.data.forEach((inst) => mapInstIdToPrice.set(inst.instId, Number(inst.idxPx)));\n return mapInstIdToPrice;\n }),\n repeat({ delay: 1000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const tradingAccountId$ = accountUid$.pipe(\n map((uid) => `okx/${uid}/trading`),\n shareReplay(1),\n);\n\ndefer(async () => {\n const tradingAccountId = await firstValueFrom(tradingAccountId$);\n addAccountMarket(terminal, { account_id: tradingAccountId, market_id: 'OKX' });\n\n provideAccountInfoService(\n terminal,\n tradingAccountId,\n async () => {\n const [positionsApi, balanceApi, mapProductIdToProduct, marketIndexTickerUSDT] = await Promise.all([\n client.getAccountPositions({}),\n client.getAccountBalance({}),\n firstValueFrom(productService.mapProductIdToProduct$),\n firstValueFrom(marketIndexTickerUSDT$),\n ]);\n\n let totalEquity = 0;\n let totalFree = 0;\n const positions: IPosition[] = [];\n\n balanceApi.data[0]?.details.forEach((detail) => {\n if (detail.ccy === 'USDT') {\n const balance = +(detail.cashBal ?? 0);\n const free = Math.min(\n balance, // free should no more than balance if there is much profits\n +(detail.availEq ?? 0),\n );\n const equity = +(detail.eq ?? 0) - +(detail.stgyEq ?? 0);\n totalEquity += equity;\n totalFree += free;\n } else {\n const volume = +(detail.cashBal ?? 0);\n const free_volume = Math.min(\n volume, // free should no more than balance if there is much profits\n +(detail.availEq ?? 0),\n );\n const closable_price = marketIndexTickerUSDT.get(detail.ccy + '-USDT') || 0;\n const delta_equity = volume * closable_price || 0;\n const delta_profit = +detail.totalPnl || 0;\n\n const product_id = encodePath('SPOT', `${detail.ccy}-USDT`);\n positions.push({\n position_id: product_id,\n datasource_id: 'OKX',\n product_id: product_id,\n direction: 'LONG',\n volume: volume,\n free_volume: free_volume,\n position_price: +detail.accAvgPx,\n floating_profit: delta_profit,\n closable_price: closable_price,\n valuation: delta_equity,\n });\n\n totalEquity += delta_equity;\n }\n });\n positionsApi.data.forEach((x) => {\n const direction =\n x.posSide === 'long' ? 'LONG' : x.posSide === 'short' ? 'SHORT' : +x.pos > 0 ? 'LONG' : 'SHORT';\n const volume = Math.abs(+x.pos);\n const product_id = encodePath(x.instType, x.instId);\n const closable_price = +x.last;\n const valuation =\n (mapProductIdToProduct.get(product_id)?.value_scale ?? 1) * volume * closable_price || 0;\n\n positions.push({\n position_id: x.posId,\n datasource_id: 'OKX',\n product_id,\n direction,\n volume: volume,\n free_volume: +x.availPos,\n closable_price,\n position_price: +x.avgPx,\n floating_profit: +x.upl,\n valuation,\n });\n });\n return {\n money: {\n currency: 'USDT',\n equity: totalEquity,\n free: totalFree,\n },\n positions: positions,\n };\n },\n { auto_refresh_interval: 1000 },\n );\n}).subscribe();\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n\n const fundingAccountId = `okx/${uid}/funding/USDT`;\n\n provideAccountInfoService(\n terminal,\n fundingAccountId,\n async () => {\n const [assetBalances, marketIndexTickerUSDT] = await Promise.all([\n client.getAssetBalances({}),\n firstValueFrom(marketIndexTickerUSDT$),\n ]);\n\n const positions: IPosition[] = [];\n let equity = 0;\n let free = 0;\n\n assetBalances.data.forEach((x) => {\n if (x.ccy === 'USDT') {\n const balance = +x.bal;\n equity += balance;\n free += balance;\n return;\n }\n\n const price = marketIndexTickerUSDT.get(`${x.ccy}-USDT`) || 0;\n const valuation = price * +x.bal || 0;\n const productId = encodePath('SPOT', `${x.ccy}-USDT`);\n\n positions.push({\n datasource_id: 'OKX',\n position_id: productId,\n product_id: productId,\n direction: 'LONG',\n volume: +x.bal,\n free_volume: +x.bal,\n position_price: price,\n floating_profit: 0,\n closable_price: price,\n valuation,\n });\n\n equity += valuation;\n });\n\n return {\n money: {\n currency: 'USDT',\n equity,\n free,\n },\n positions,\n };\n },\n { auto_refresh_interval: 1000 },\n );\n}).subscribe();\n\ndefer(async () => {\n const uid = await firstValueFrom(accountUid$);\n const earningAccountId = `okx/${uid}/earning/USDT`;\n provideAccountInfoService(\n terminal,\n earningAccountId,\n async () => {\n const offers = await client.getFinanceSavingsBalance({});\n const equity = offers.data.filter((x) => x.ccy === 'USDT').reduce((acc, x) => acc + +x.amt, 0);\n const free = equity;\n return {\n money: {\n currency: 'USDT',\n equity,\n free,\n },\n positions: [],\n };\n },\n { auto_refresh_interval: 5000 },\n );\n}).subscribe();\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-service.d.ts","sourceRoot":"","sources":["../src/api-service.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const protocol_1 = require("@yuants/protocol");
|
|
4
|
+
const public_api_1 = require("./public-api");
|
|
5
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
6
|
+
terminal.server.provideService('OKX/PositionTiers', {
|
|
7
|
+
required: ['instType', 'tdMode'],
|
|
8
|
+
properties: {
|
|
9
|
+
instType: { type: 'string' },
|
|
10
|
+
tdMode: { type: 'string' },
|
|
11
|
+
instFamily: { type: 'string' },
|
|
12
|
+
instId: { type: 'string' },
|
|
13
|
+
uly: { type: 'string' },
|
|
14
|
+
ccy: { type: 'string' },
|
|
15
|
+
tier: { type: 'string' },
|
|
16
|
+
},
|
|
17
|
+
}, async (msg) => {
|
|
18
|
+
const data = await (0, public_api_1.getPositionTiers)(msg.req);
|
|
19
|
+
return {
|
|
20
|
+
res: {
|
|
21
|
+
code: 0,
|
|
22
|
+
message: 'OK',
|
|
23
|
+
data,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}, {
|
|
27
|
+
concurrent: 1,
|
|
28
|
+
egress_token_capacity: 10,
|
|
29
|
+
egress_token_refill_interval: 2100,
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=api-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-service.js","sourceRoot":"","sources":["../src/api-service.ts"],"names":[],"mappings":";;AAAA,+CAA4C;AAC5C,6CAAgD;AAEhD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAY5B,mBAAmB,EACnB;IACE,QAAQ,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAChC,UAAU,EAAE;QACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC1B,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACvB,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACvB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACzB;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,IAAI,GAAG,MAAM,IAAA,6BAAgB,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO;QACL,GAAG,EAAE;YACH,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,IAAI;YACb,IAAI;SACL;KACF,CAAC;AACJ,CAAC,EACD;IACE,UAAU,EAAE,CAAC;IACb,qBAAqB,EAAE,EAAE;IACzB,4BAA4B,EAAE,IAAI;CACnC,CACF,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { getPositionTiers } from './public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<\n {\n instType: string;\n tdMode: string;\n instFamily?: string;\n instId?: string;\n uly?: string;\n ccy?: string;\n tier?: string;\n },\n Awaited<ReturnType<typeof getPositionTiers>>\n>(\n 'OKX/PositionTiers',\n {\n required: ['instType', 'tdMode'],\n properties: {\n instType: { type: 'string' },\n tdMode: { type: 'string' },\n instFamily: { type: 'string' },\n instId: { type: 'string' },\n uly: { type: 'string' },\n ccy: { type: 'string' },\n tier: { type: 'string' },\n },\n },\n async (msg) => {\n const data = await getPositionTiers(msg.req);\n return {\n res: {\n code: 0,\n message: 'OK',\n data,\n },\n };\n },\n {\n concurrent: 1,\n egress_token_capacity: 10,\n egress_token_refill_interval: 2100,\n },\n);\n"]}
|