@yuants/vendor-binance 0.8.2 → 0.8.3

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.
Files changed (62) hide show
  1. package/dist/api/private-api.js +46 -1
  2. package/dist/api/private-api.js.map +1 -1
  3. package/dist/api/public-api.js +3 -5
  4. package/dist/api/public-api.js.map +1 -1
  5. package/dist/index.js +4 -4
  6. package/dist/index.js.map +1 -1
  7. package/dist/public-data/interest_rate.js +82 -0
  8. package/dist/public-data/interest_rate.js.map +1 -0
  9. package/dist/public-data/ohlc.js +88 -0
  10. package/dist/public-data/ohlc.js.map +1 -0
  11. package/dist/{product.js → public-data/product.js} +1 -1
  12. package/dist/public-data/product.js.map +1 -0
  13. package/dist/{quote.js → public-data/quote.js} +53 -5
  14. package/dist/public-data/quote.js.map +1 -0
  15. package/dist/services/order-actions-with-credential.js +3 -1
  16. package/dist/services/order-actions-with-credential.js.map +1 -1
  17. package/dist/services/orders/modifyOrder.js +58 -0
  18. package/dist/services/orders/modifyOrder.js.map +1 -0
  19. package/lib/api/private-api.d.ts +97 -0
  20. package/lib/api/private-api.d.ts.map +1 -1
  21. package/lib/api/private-api.js +51 -1
  22. package/lib/api/private-api.js.map +1 -1
  23. package/lib/api/public-api.d.ts +11 -6
  24. package/lib/api/public-api.d.ts.map +1 -1
  25. package/lib/api/public-api.js +5 -7
  26. package/lib/api/public-api.js.map +1 -1
  27. package/lib/index.d.ts +4 -4
  28. package/lib/index.d.ts.map +1 -1
  29. package/lib/index.js +4 -4
  30. package/lib/index.js.map +1 -1
  31. package/lib/public-data/interest_rate.d.ts.map +1 -0
  32. package/lib/public-data/interest_rate.js +84 -0
  33. package/lib/public-data/interest_rate.js.map +1 -0
  34. package/lib/public-data/ohlc.d.ts +2 -0
  35. package/lib/public-data/ohlc.d.ts.map +1 -0
  36. package/lib/{interest_rate.js → public-data/ohlc.js} +55 -22
  37. package/lib/public-data/ohlc.js.map +1 -0
  38. package/lib/{product.d.ts.map → public-data/product.d.ts.map} +1 -1
  39. package/lib/{product.js → public-data/product.js} +1 -1
  40. package/lib/public-data/product.js.map +1 -0
  41. package/lib/{quote.d.ts.map → public-data/quote.d.ts.map} +1 -1
  42. package/lib/{quote.js → public-data/quote.js} +52 -4
  43. package/lib/public-data/quote.js.map +1 -0
  44. package/lib/services/order-actions-with-credential.js +3 -1
  45. package/lib/services/order-actions-with-credential.js.map +1 -1
  46. package/lib/services/orders/modifyOrder.d.ts +4 -0
  47. package/lib/services/orders/modifyOrder.d.ts.map +1 -0
  48. package/lib/services/orders/modifyOrder.js +62 -0
  49. package/lib/services/orders/modifyOrder.js.map +1 -0
  50. package/package.json +1 -1
  51. package/temp/package-deps.json +13 -11
  52. package/dist/interest_rate.js +0 -55
  53. package/dist/interest_rate.js.map +0 -1
  54. package/dist/product.js.map +0 -1
  55. package/dist/quote.js.map +0 -1
  56. package/lib/interest_rate.d.ts.map +0 -1
  57. package/lib/interest_rate.js.map +0 -1
  58. package/lib/product.js.map +0 -1
  59. package/lib/quote.js.map +0 -1
  60. /package/lib/{interest_rate.d.ts → public-data/interest_rate.d.ts} +0 -0
  61. /package/lib/{product.d.ts → public-data/product.d.ts} +0 -0
  62. /package/lib/{quote.d.ts → public-data/quote.d.ts} +0 -0
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
3
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
4
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
5
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
6
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
7
+ function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
8
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
9
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
10
+ function fulfill(value) { resume("next", value); }
11
+ function reject(value) { resume("throw", value); }
12
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const data_series_1 = require("@yuants/data-series");
16
+ const protocol_1 = require("@yuants/protocol");
17
+ const utils_1 = require("@yuants/utils");
18
+ const rxjs_1 = require("rxjs");
19
+ const public_api_1 = require("../api/public-api");
20
+ const private_api_1 = require("../api/private-api");
21
+ const terminal = protocol_1.Terminal.fromNodeEnv();
22
+ (0, data_series_1.createSeriesProvider)(terminal, {
23
+ tableName: 'interest_rate',
24
+ series_id_prefix_parts: ['BINANCE'],
25
+ reversed: true,
26
+ serviceOptions: { concurrent: 1 },
27
+ queryFn: function ({ series_id, started_at, ended_at }) {
28
+ return __asyncGenerator(this, arguments, function* () {
29
+ const [datasource_id, product_id] = (0, utils_1.decodePath)(series_id);
30
+ let current_start = started_at;
31
+ const [instType, symbol] = (0, utils_1.decodePath)(product_id);
32
+ if (instType === 'usdt-future') {
33
+ while (true) {
34
+ // 向前翻页,时间降序
35
+ const res = yield __await((0, public_api_1.getFutureFundingRate)({
36
+ symbol: symbol,
37
+ startTime: current_start,
38
+ endTime: ended_at,
39
+ limit: 1000,
40
+ }));
41
+ yield yield __await(res.map((v) => ({
42
+ series_id,
43
+ created_at: (0, utils_1.formatTime)(v.fundingTime),
44
+ datasource_id,
45
+ product_id,
46
+ long_rate: `${-v.fundingRate}`,
47
+ short_rate: `${v.fundingRate}`,
48
+ settlement_price: '',
49
+ })));
50
+ if (res.length < 1000) {
51
+ break;
52
+ }
53
+ current_start = +res[res.length - 1].fundingTime;
54
+ yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(1000)));
55
+ }
56
+ }
57
+ else if (instType === 'margin') {
58
+ while (true) {
59
+ const res = yield __await((0, private_api_1.getMarginInterestRateHistory)({
60
+ asset: symbol,
61
+ startTime: current_start,
62
+ endTime: ended_at,
63
+ limit: 100,
64
+ }));
65
+ yield yield __await(res.map((v) => ({
66
+ series_id,
67
+ created_at: (0, utils_1.formatTime)(v.timestamp),
68
+ datasource_id,
69
+ product_id,
70
+ long_rate: v.dailyInterestRate,
71
+ short_rate: '0',
72
+ settlement_price: '',
73
+ })));
74
+ if (res.length < 100) {
75
+ break;
76
+ }
77
+ current_start = +res[res.length - 1].timestamp;
78
+ yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(1000)));
79
+ }
80
+ }
81
+ });
82
+ },
83
+ });
84
+ //# sourceMappingURL=interest_rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../../src/public-data/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,qDAA2D;AAC3D,+CAA4C;AAC5C,yCAAuD;AACvD,+BAA6C;AAC7C,kDAAyD;AACzD,oDAAkE;AAElE,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,IAAA,kCAAoB,EAAgB,QAAQ,EAAE;IAC5C,SAAS,EAAE,eAAe;IAC1B,sBAAsB,EAAE,CAAC,SAAS,CAAC;IACnC,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;IACjC,OAAO,EAAE,UAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;;YAC3D,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,IAAA,kBAAU,EAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,aAAa,GAAG,UAAU,CAAC;YAC/B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;YAClD,IAAI,QAAQ,KAAK,aAAa,EAAE;gBAC9B,OAAO,IAAI,EAAE;oBACX,YAAY;oBACZ,MAAM,GAAG,GAAG,cAAM,IAAA,iCAAoB,EAAC;wBACrC,MAAM,EAAE,MAAM;wBACd,SAAS,EAAE,aAAa;wBACxB,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,IAAI;qBACZ,CAAC,CAAA,CAAC;oBACH,oBAAM,GAAG,CAAC,GAAG,CACX,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC;wBACrB,SAAS;wBACT,UAAU,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,WAAW,CAAC;wBACrC,aAAa;wBACb,UAAU;wBACV,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE;wBAC9B,UAAU,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;wBAC9B,gBAAgB,EAAE,EAAE;qBACrB,CAAC,CACH,CAAA,CAAC;oBACF,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE;wBACrB,MAAM;qBACP;oBACD,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;oBACjD,cAAM,IAAA,qBAAc,EAAC,IAAA,YAAK,EAAC,IAAI,CAAC,CAAC,CAAA,CAAC;iBACnC;aACF;iBAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE;gBAChC,OAAO,IAAI,EAAE;oBACX,MAAM,GAAG,GAAG,cAAM,IAAA,0CAA4B,EAAC;wBAC7C,KAAK,EAAE,MAAM;wBACb,SAAS,EAAE,aAAa;wBACxB,OAAO,EAAE,QAAQ;wBACjB,KAAK,EAAE,GAAG;qBACX,CAAC,CAAA,CAAC;oBACH,oBAAM,GAAG,CAAC,GAAG,CACX,CAAC,CAKA,EAAiB,EAAE,CAAC,CAAC;wBACpB,SAAS;wBACT,UAAU,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,SAAS,CAAC;wBACnC,aAAa;wBACb,UAAU;wBACV,SAAS,EAAE,CAAC,CAAC,iBAAiB;wBAC9B,UAAU,EAAE,GAAG;wBACf,gBAAgB,EAAE,EAAE;qBACrB,CAAC,CACH,CAAA,CAAC;oBACF,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;wBACpB,MAAM;qBACP;oBACD,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC/C,cAAM,IAAA,qBAAc,EAAC,IAAA,YAAK,EAAC,IAAI,CAAC,CAAC,CAAA,CAAC;iBACnC;aACF;QACH,CAAC;KAAA;CACF,CAAC,CAAC","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { decodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, timer } from 'rxjs';\nimport { getFutureFundingRate } from '../api/public-api';\nimport { getMarginInterestRateHistory } from '../api/private-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\ncreateSeriesProvider<IInterestRate>(terminal, {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['BINANCE'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const [datasource_id, product_id] = decodePath(series_id);\n let current_start = started_at;\n const [instType, symbol] = decodePath(product_id);\n if (instType === 'usdt-future') {\n while (true) {\n // 向前翻页,时间降序\n const res = await getFutureFundingRate({\n symbol: symbol,\n startTime: current_start,\n endTime: ended_at,\n limit: 1000,\n });\n yield res.map(\n (v): IInterestRate => ({\n series_id,\n created_at: formatTime(v.fundingTime),\n datasource_id,\n product_id,\n long_rate: `${-v.fundingRate}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n if (res.length < 1000) {\n break;\n }\n current_start = +res[res.length - 1].fundingTime;\n await firstValueFrom(timer(1000));\n }\n } else if (instType === 'margin') {\n while (true) {\n const res = await getMarginInterestRateHistory({\n asset: symbol,\n startTime: current_start,\n endTime: ended_at,\n limit: 100,\n });\n yield res.map(\n (v: {\n asset: string;\n dailyInterestRate: string;\n timestamp: number;\n vipLevel: number;\n }): IInterestRate => ({\n series_id,\n created_at: formatTime(v.timestamp),\n datasource_id,\n product_id,\n long_rate: v.dailyInterestRate,\n short_rate: '0',\n settlement_price: '',\n }),\n );\n if (res.length < 100) {\n break;\n }\n current_start = +res[res.length - 1].timestamp;\n await firstValueFrom(timer(1000));\n }\n }\n },\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ohlc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ohlc.d.ts","sourceRoot":"","sources":["../../src/public-data/ohlc.ts"],"names":[],"mappings":""}
@@ -16,42 +16,75 @@ const data_series_1 = require("@yuants/data-series");
16
16
  const protocol_1 = require("@yuants/protocol");
17
17
  const utils_1 = require("@yuants/utils");
18
18
  const rxjs_1 = require("rxjs");
19
- const public_api_1 = require("./api/public-api");
19
+ const client_1 = require("../api/client");
20
20
  const terminal = protocol_1.Terminal.fromNodeEnv();
21
+ const DURATION_TO_BINANCE_INTERVAL = {
22
+ PT1M: '1m',
23
+ PT3M: '3m',
24
+ PT5M: '5m',
25
+ PT15M: '15m',
26
+ PT30M: '30m',
27
+ PT1H: '1h',
28
+ PT2H: '2h',
29
+ PT4H: '4h',
30
+ PT6H: '6h',
31
+ PT8H: '8h',
32
+ PT12H: '12h',
33
+ P1D: '1d',
34
+ P3D: '3d',
35
+ P1W: '1w',
36
+ P1M: '1M',
37
+ };
21
38
  (0, data_series_1.createSeriesProvider)(terminal, {
22
- tableName: 'interest_rate',
39
+ tableName: 'ohlc',
23
40
  series_id_prefix_parts: ['BINANCE'],
24
41
  reversed: true,
25
- serviceOptions: { concurrent: 1 },
42
+ serviceOptions: { concurrent: 10 },
26
43
  queryFn: function ({ series_id, started_at, ended_at }) {
27
44
  return __asyncGenerator(this, arguments, function* () {
28
- const [datasource_id, product_id] = (0, utils_1.decodePath)(series_id);
29
- let current_start = started_at;
45
+ const [datasource_id, product_id, duration] = (0, utils_1.decodePath)(series_id);
46
+ const interval = DURATION_TO_BINANCE_INTERVAL[duration];
47
+ if (!interval) {
48
+ throw new Error(`Unsupported duration: ${duration}`);
49
+ }
50
+ const offset = (0, utils_1.convertDurationToOffset)(duration);
30
51
  const [instType, symbol] = (0, utils_1.decodePath)(product_id);
52
+ let current_end = ended_at || Date.now();
53
+ const start = started_at || 0;
54
+ const baseUrl = instType === 'usdt-future'
55
+ ? 'https://fapi.binance.com/fapi/v1/klines'
56
+ : 'https://api.binance.com/api/v3/klines';
31
57
  while (true) {
32
- // 向前翻页,时间降序
33
- const res = yield __await((0, public_api_1.getFutureFundingRate)({
34
- symbol: symbol,
35
- startTime: current_start,
36
- endTime: ended_at,
58
+ const res = yield __await((0, client_1.requestPublic)('GET', baseUrl, {
59
+ symbol,
60
+ interval,
61
+ endTime: current_end,
37
62
  limit: 1000,
38
63
  }));
39
- yield yield __await(res.map((v) => ({
40
- series_id,
41
- created_at: (0, utils_1.formatTime)(v.fundingTime),
64
+ if (res.length === 0)
65
+ break;
66
+ const periods = res.map((k) => ({
42
67
  datasource_id,
43
68
  product_id,
44
- long_rate: `${-v.fundingRate}`,
45
- short_rate: `${v.fundingRate}`,
46
- settlement_price: '',
47
- })));
48
- if (res.length < 1000) {
69
+ duration,
70
+ created_at: (0, utils_1.formatTime)(k[0]),
71
+ closed_at: (0, utils_1.formatTime)(k[0] + offset),
72
+ open: `${k[1]}`,
73
+ high: `${k[2]}`,
74
+ low: `${k[3]}`,
75
+ close: `${k[4]}`,
76
+ volume: `${k[5]}`,
77
+ open_interest: '0',
78
+ series_id,
79
+ }));
80
+ yield yield __await(periods);
81
+ const oldest = periods[0];
82
+ current_end = new Date(oldest.created_at).getTime() - 1;
83
+ if (current_end < start)
49
84
  break;
50
- }
51
- current_start = +res[res.length - 1].fundingTime;
52
- yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(1000)));
85
+ yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(200)));
53
86
  }
54
87
  });
55
88
  },
56
89
  });
57
- //# sourceMappingURL=interest_rate.js.map
90
+ //# sourceMappingURL=ohlc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../../src/public-data/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, timer } from 'rxjs';\nimport { requestPublic } from '../api/client';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst DURATION_TO_BINANCE_INTERVAL: Record<string, string> = {\n PT1M: '1m',\n PT3M: '3m',\n PT5M: '5m',\n PT15M: '15m',\n PT30M: '30m',\n PT1H: '1h',\n PT2H: '2h',\n PT4H: '4h',\n PT6H: '6h',\n PT8H: '8h',\n PT12H: '12h',\n P1D: '1d',\n P3D: '3d',\n P1W: '1w',\n P1M: '1M',\n};\n\ncreateSeriesProvider<IOHLC>(terminal, {\n tableName: 'ohlc',\n series_id_prefix_parts: ['BINANCE'],\n reversed: true,\n serviceOptions: { concurrent: 10 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const interval = DURATION_TO_BINANCE_INTERVAL[duration];\n if (!interval) {\n throw new Error(`Unsupported duration: ${duration}`);\n }\n const offset = convertDurationToOffset(duration);\n const [instType, symbol] = decodePath(product_id);\n\n let current_end = ended_at || Date.now();\n const start = started_at || 0;\n\n const baseUrl =\n instType === 'usdt-future'\n ? 'https://fapi.binance.com/fapi/v1/klines'\n : 'https://api.binance.com/api/v3/klines';\n\n type IBinanceKline = [\n number, // Open time\n string, // Open\n string, // High\n string, // Low\n string, // Close\n string, // Volume\n number, // Close time\n string, // Quote asset volume\n number, // Number of trades\n string, // Taker buy base asset volume\n string, // Taker buy quote asset volume\n string, // Ignore\n ];\n\n while (true) {\n const res = await requestPublic<IBinanceKline[]>('GET', baseUrl, {\n symbol,\n interval,\n endTime: current_end,\n limit: 1000,\n });\n\n if (res.length === 0) break;\n\n const periods: IOHLC[] = res.map((k) => ({\n datasource_id,\n product_id,\n duration,\n created_at: formatTime(k[0]),\n closed_at: formatTime(k[0] + offset),\n open: `${k[1]}`,\n high: `${k[2]}`,\n low: `${k[3]}`,\n close: `${k[4]}`,\n volume: `${k[5]}`,\n open_interest: '0',\n series_id,\n }));\n\n yield periods;\n\n const oldest = periods[0];\n current_end = new Date(oldest.created_at).getTime() - 1;\n\n if (current_end < start) break;\n\n await firstValueFrom(timer(200));\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../../src/public-data/product.ts"],"names":[],"mappings":""}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const data_product_1 = require("@yuants/data-product");
4
4
  const protocol_1 = require("@yuants/protocol");
5
5
  const utils_1 = require("@yuants/utils");
6
- const public_api_1 = require("./api/public-api");
6
+ const public_api_1 = require("../api/public-api");
7
7
  const terminal = protocol_1.Terminal.fromNodeEnv();
8
8
  // Provide QueryProducts service with the new design
9
9
  const cache = (0, data_product_1.provideQueryProductsService)(terminal, 'BINANCE', async (req) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../../src/public-data/product.ts"],"names":[],"mappings":";;AAAA,uDAAoG;AACpG,+CAA4C;AAC5C,yCAA2C;AAC3C,kDAA0D;AAE1D,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,oDAAoD;AACpD,MAAM,KAAK,GAAG,IAAA,0CAA2B,EACvC,QAAQ,EACR,SAAS,EACT,KAAK,EAAE,GAA0B,EAAuB,EAAE;IACxD,sDAAsD;IACtD,MAAM,YAAY,GAAG,MAAM,IAAA,kCAAqB,GAAE,CAAC;IAEnD,qCAAqC;IACrC,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAY,EAAE;QACnD,OAAO;YACL,aAAa,EAAE,SAAS;YACxB,UAAU,EAAE,IAAA,kBAAU,EAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;YACpD,aAAa,EAAE,MAAM,CAAC,SAAS;YAC/B,cAAc,EAAE,MAAM,CAAC,UAAU;YACjC,UAAU,EAAE,CAAC,MAAM,MAAM,CAAC,cAAc,EAAE;YAC1C,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC,MAAM,MAAM,CAAC,iBAAiB,EAAE;YAC9C,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,OAAO;YACrD,gBAAgB,EAAE,EAAE;YACpB,WAAW,EAAE,CAAC,MAAM,CAAC,qBAAqB,GAAG,GAAG;YAChD,gBAAgB,EAAE,CAAC;YACnB,iBAAiB,EAAE,CAAC;YACpB,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,qBAAqB;YAChC,gBAAgB,EAAE,KAAK;SACxB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,EACD;IACE,qBAAqB,EAAE,OAAQ;CAChC,CACF,CAAC","sourcesContent":["import { IProduct, IQueryProductsRequest, provideQueryProductsService } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFutureExchangeInfo } from '../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\n// Provide QueryProducts service with the new design\nconst cache = provideQueryProductsService(\n terminal,\n 'BINANCE',\n async (req: IQueryProductsRequest): Promise<IProduct[]> => {\n // Directly call the external API to get exchange info\n const exchangeInfo = await getFutureExchangeInfo();\n\n // Convert symbols to IProduct format\n return exchangeInfo.symbols.map((symbol): IProduct => {\n return {\n datasource_id: 'BINANCE',\n product_id: encodePath('usdt-future', symbol.symbol),\n base_currency: symbol.baseAsset,\n quote_currency: symbol.quoteAsset,\n price_step: +`1e-${symbol.pricePrecision}`,\n value_scale: 1,\n volume_step: +`1e-${symbol.quantityPrecision}`,\n name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,\n value_scale_unit: '',\n margin_rate: +symbol.requiredMarginPercent / 100,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'BINANCE/USDT-FUTURE',\n no_interest_rate: false,\n };\n });\n },\n {\n auto_refresh_interval: 3600_000,\n },\n);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../src/quote.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../src/public-data/quote.ts"],"names":[],"mappings":""}
@@ -5,7 +5,8 @@ const protocol_1 = require("@yuants/protocol");
5
5
  const sql_1 = require("@yuants/sql");
6
6
  const utils_1 = require("@yuants/utils");
7
7
  const rxjs_1 = require("rxjs");
8
- const public_api_1 = require("./api/public-api");
8
+ const private_api_1 = require("../api/private-api");
9
+ const public_api_1 = require("../api/public-api");
9
10
  const terminal = protocol_1.Terminal.fromNodeEnv();
10
11
  const OPEN_INTEREST_TTL = process.env.OPEN_INTEREST_TTL ? Number(process.env.OPEN_INTEREST_TTL) : 120000;
11
12
  const openInterestCache = (0, cache_1.createCache)(async (symbol) => {
@@ -29,7 +30,14 @@ const quoteFromPremiumIndex$ = futurePremiumIndex$.pipe((0, rxjs_1.mergeMap)((en
29
30
  datasource_id: 'BINANCE',
30
31
  product_id: (0, utils_1.encodePath)('usdt-future', entry.symbol),
31
32
  last_price: entry.markPrice,
32
- updated_at: new Date((_a = entry.time) !== null && _a !== void 0 ? _a : Date.now()).toISOString(),
33
+ // interestRate is the predicted funding rate for next settlement
34
+ // In perpetual futures: when funding rate > 0, longs pay shorts
35
+ // interest_rate_long: cost for holding long (negative of funding rate)
36
+ // interest_rate_short: income for holding short (positive of funding rate)
37
+ interest_rate_long: entry.interestRate,
38
+ interest_rate_short: `${-Number(entry.interestRate)}`,
39
+ interest_rate_next_settled_at: (0, utils_1.formatTime)(entry.nextFundingTime),
40
+ updated_at: (0, utils_1.formatTime)((_a = entry.time) !== null && _a !== void 0 ? _a : Date.now()),
33
41
  });
34
42
  }));
35
43
  const quoteFromBookTicker$ = futureBookTicker$.pipe((0, rxjs_1.mergeMap)((entries) => (0, rxjs_1.from)(entries || [])), (0, rxjs_1.map)((entry) => {
@@ -39,7 +47,7 @@ const quoteFromBookTicker$ = futureBookTicker$.pipe((0, rxjs_1.mergeMap)((entrie
39
47
  product_id: (0, utils_1.encodePath)('usdt-future', entry.symbol),
40
48
  bid_price: entry.bidPrice,
41
49
  ask_price: entry.askPrice,
42
- updated_at: new Date((_a = entry.time) !== null && _a !== void 0 ? _a : Date.now()).toISOString(),
50
+ updated_at: (0, utils_1.formatTime)((_a = entry.time) !== null && _a !== void 0 ? _a : Date.now()),
43
51
  });
44
52
  }));
45
53
  const quoteFromOpenInterest$ = futureBookTicker$.pipe((0, rxjs_1.mergeMap)((entries) => (0, rxjs_1.from)(entries || [])), (0, rxjs_1.mergeMap)((entry) => (0, rxjs_1.from)(openInterestCache.query(entry.symbol)).pipe((0, rxjs_1.map)((openInterest) => ({
@@ -47,7 +55,47 @@ const quoteFromOpenInterest$ = futureBookTicker$.pipe((0, rxjs_1.mergeMap)((entr
47
55
  product_id: (0, utils_1.encodePath)('usdt-future', entry.symbol),
48
56
  open_interest: `${openInterest !== null && openInterest !== void 0 ? openInterest : 0}`,
49
57
  }))), 5));
50
- const quote$ = (0, rxjs_1.merge)(quoteFromPremiumIndex$, quoteFromBookTicker$, quoteFromOpenInterest$).pipe((0, rxjs_1.groupBy)((quote) => quote.product_id), (0, rxjs_1.mergeMap)((group$) => group$.pipe((0, rxjs_1.scan)((acc, cur) => Object.assign(acc, cur, {
58
+ const quoteFromSpotBookTicker$ = (0, rxjs_1.defer)(() => (0, public_api_1.getSpotBookTicker)({})).pipe((0, rxjs_1.repeat)({ delay: 1000 }), (0, rxjs_1.retry)({ delay: 30000 }), (0, rxjs_1.shareReplay)({ bufferSize: 1, refCount: true }), (0, rxjs_1.mergeMap)((entries) => (0, rxjs_1.from)(entries || [])), (0, rxjs_1.map)((entry) => ({
59
+ datasource_id: 'BINANCE',
60
+ product_id: (0, utils_1.encodePath)('spot', entry.symbol),
61
+ bid_price: entry.bidPrice,
62
+ ask_price: entry.askPrice,
63
+ bid_volume: entry.bidQty,
64
+ ask_volume: entry.askQty,
65
+ updated_at: (0, utils_1.formatTime)(Date.now()),
66
+ })));
67
+ const marginInterestRateCache = (0, cache_1.createCache)(async (asset) => {
68
+ var _a;
69
+ try {
70
+ const data = await (0, private_api_1.getMarginNextHourlyInterestRate)({
71
+ assets: asset,
72
+ isIsolated: false,
73
+ });
74
+ return (_a = data[0]) === null || _a === void 0 ? void 0 : _a.nextHourlyInterestRate;
75
+ }
76
+ catch (err) {
77
+ return undefined;
78
+ }
79
+ }, {
80
+ expire: 60000,
81
+ });
82
+ const marginPairs$ = (0, rxjs_1.defer)(() => (0, private_api_1.getMarginAllPairs)()).pipe((0, rxjs_1.repeat)({ delay: 3600000 }), // Refresh pair list hourly
83
+ (0, rxjs_1.retry)({ delay: 60000 }), (0, rxjs_1.shareReplay)({ bufferSize: 1, refCount: true }));
84
+ const quoteFromMarginRates$ = marginPairs$.pipe((0, rxjs_1.mergeMap)((pairs) => (0, rxjs_1.from)(pairs).pipe((0, rxjs_1.mergeMap)((pair) => (0, rxjs_1.defer)(async () => {
85
+ const [baseRate, quoteRate] = await Promise.all([
86
+ marginInterestRateCache.query(pair.base),
87
+ marginInterestRateCache.query(pair.quote),
88
+ ]);
89
+ return {
90
+ datasource_id: 'BINANCE',
91
+ product_id: (0, utils_1.encodePath)('spot', pair.symbol),
92
+ // User instruction: Long = Quote Rate, Short = Base Rate
93
+ interest_rate_long: quoteRate,
94
+ interest_rate_short: baseRate,
95
+ updated_at: (0, utils_1.formatTime)(Date.now()),
96
+ };
97
+ }), 5))), (0, rxjs_1.repeat)({ delay: 60000 }));
98
+ const quote$ = (0, rxjs_1.merge)(quoteFromPremiumIndex$, quoteFromBookTicker$, quoteFromOpenInterest$, quoteFromSpotBookTicker$, quoteFromMarginRates$).pipe((0, rxjs_1.groupBy)((quote) => quote.product_id), (0, rxjs_1.mergeMap)((group$) => group$.pipe((0, rxjs_1.scan)((acc, cur) => Object.assign(acc, cur, {
51
99
  datasource_id: 'BINANCE',
52
100
  product_id: group$.key,
53
101
  }), {}))), (0, rxjs_1.share)(), (0, rxjs_1.shareReplay)({ bufferSize: 1, refCount: true }));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote.js","sourceRoot":"","sources":["../../src/public-data/quote.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { writeToSQL } from '@yuants/sql';\nimport { decodePath, encodePath, formatTime } from '@yuants/utils';\nimport {\n defer,\n filter,\n from,\n groupBy,\n map,\n merge,\n mergeMap,\n repeat,\n retry,\n scan,\n share,\n shareReplay,\n} from 'rxjs';\nimport { getMarginAllPairs, getMarginNextHourlyInterestRate, IMarginPair } from '../api/private-api';\nimport {\n getFutureBookTicker,\n getFutureOpenInterest,\n getFuturePremiumIndex,\n getSpotBookTicker,\n} from '../api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\nconst OPEN_INTEREST_TTL = process.env.OPEN_INTEREST_TTL ? Number(process.env.OPEN_INTEREST_TTL) : 120_000;\n\nconst openInterestCache = createCache<number>(\n async (symbol: string) => {\n try {\n const data = await getFutureOpenInterest({ symbol });\n return Number(data.openInterest ?? 0);\n } catch (err) {\n console.warn('getFutureOpenInterest failed', symbol, err);\n return undefined;\n }\n },\n {\n expire: OPEN_INTEREST_TTL,\n },\n);\n\nconst futurePremiumIndex$ = defer(() => getFuturePremiumIndex({})).pipe(\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nconst futureBookTicker$ = defer(() => getFutureBookTicker({})).pipe(\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nconst quoteFromPremiumIndex$ = futurePremiumIndex$.pipe(\n mergeMap((entries) => from(entries || [])),\n map(\n (entry): Partial<IQuote> => ({\n datasource_id: 'BINANCE',\n product_id: encodePath('usdt-future', entry.symbol),\n last_price: entry.markPrice,\n // interestRate is the predicted funding rate for next settlement\n // In perpetual futures: when funding rate > 0, longs pay shorts\n // interest_rate_long: cost for holding long (negative of funding rate)\n // interest_rate_short: income for holding short (positive of funding rate)\n interest_rate_long: entry.interestRate,\n interest_rate_short: `${-Number(entry.interestRate)}`,\n interest_rate_next_settled_at: formatTime(entry.nextFundingTime),\n updated_at: formatTime(entry.time ?? Date.now()),\n }),\n ),\n);\n\nconst quoteFromBookTicker$ = futureBookTicker$.pipe(\n mergeMap((entries) => from(entries || [])),\n map(\n (entry): Partial<IQuote> => ({\n datasource_id: 'BINANCE',\n product_id: encodePath('usdt-future', entry.symbol),\n bid_price: entry.bidPrice,\n ask_price: entry.askPrice,\n updated_at: formatTime(entry.time ?? Date.now()),\n }),\n ),\n);\n\nconst quoteFromOpenInterest$ = futureBookTicker$.pipe(\n mergeMap((entries) => from(entries || [])),\n mergeMap(\n (entry) =>\n from(openInterestCache.query(entry.symbol)).pipe(\n map(\n (openInterest): Partial<IQuote> => ({\n datasource_id: 'BINANCE',\n product_id: encodePath('usdt-future', entry.symbol),\n open_interest: `${openInterest ?? 0}`,\n }),\n ),\n ),\n 5,\n ),\n);\n\nconst quoteFromSpotBookTicker$ = defer(() => getSpotBookTicker({})).pipe(\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n mergeMap((entries) => from(entries || [])),\n map(\n (entry): Partial<IQuote> => ({\n datasource_id: 'BINANCE',\n product_id: encodePath('spot', entry.symbol),\n bid_price: entry.bidPrice,\n ask_price: entry.askPrice,\n bid_volume: entry.bidQty,\n ask_volume: entry.askQty,\n updated_at: formatTime(Date.now()),\n }),\n ),\n);\n\nconst marginInterestRateCache = createCache<string>(\n async (asset: string) => {\n try {\n const data = await getMarginNextHourlyInterestRate({\n assets: asset,\n isIsolated: false,\n });\n return data[0]?.nextHourlyInterestRate;\n } catch (err) {\n return undefined;\n }\n },\n {\n expire: 60_000,\n },\n);\n\nconst marginPairs$ = defer(() => getMarginAllPairs()).pipe(\n repeat({ delay: 3600_000 }), // Refresh pair list hourly\n retry({ delay: 60_000 }),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nconst quoteFromMarginRates$ = marginPairs$.pipe(\n mergeMap((pairs: IMarginPair[]) =>\n from(pairs).pipe(\n mergeMap(\n (pair) =>\n defer(async () => {\n const [baseRate, quoteRate] = await Promise.all([\n marginInterestRateCache.query(pair.base),\n marginInterestRateCache.query(pair.quote),\n ]);\n return {\n datasource_id: 'BINANCE',\n product_id: encodePath('spot', pair.symbol),\n // User instruction: Long = Quote Rate, Short = Base Rate\n interest_rate_long: quoteRate,\n interest_rate_short: baseRate,\n updated_at: formatTime(Date.now()),\n } as Partial<IQuote>;\n }),\n 5, // Concurrency\n ),\n ),\n ),\n repeat({ delay: 60_000 }),\n);\n\nconst quote$ = merge(\n quoteFromPremiumIndex$,\n quoteFromBookTicker$,\n quoteFromOpenInterest$,\n quoteFromSpotBookTicker$,\n quoteFromMarginRates$,\n).pipe(\n groupBy((quote) => quote.product_id),\n mergeMap((group$) =>\n group$.pipe(\n scan(\n (acc, cur) =>\n Object.assign(acc, cur, {\n datasource_id: 'BINANCE',\n product_id: group$.key,\n }),\n {} as Partial<IQuote>,\n ),\n ),\n ),\n share(),\n shareReplay({ bufferSize: 1, refCount: true }),\n);\n\nif (process.env.WRITE_QUOTE_TO_SQL === 'true') {\n quote$\n .pipe(\n writeToSQL({\n terminal,\n tableName: 'quote',\n writeInterval: 1_000,\n conflictKeys: ['datasource_id', 'product_id'],\n }),\n )\n .subscribe();\n\n terminal.channel.publishChannel('quote', { pattern: '^BINANCE/' }, (channel_id) => {\n const [datasourceId, productId] = decodePath(channel_id);\n if (!datasourceId || !productId) {\n throw new Error(`Invalid channel_id: ${channel_id}`);\n }\n return quote$.pipe(filter((quote) => quote.product_id === productId));\n });\n}\n"]}
@@ -2,9 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const data_order_1 = require("@yuants/data-order");
4
4
  const protocol_1 = require("@yuants/protocol");
5
- const submitOrder_1 = require("./orders/submitOrder");
6
5
  const cancelOrder_1 = require("./orders/cancelOrder");
7
6
  const listOrders_1 = require("./orders/listOrders");
7
+ const modifyOrder_1 = require("./orders/modifyOrder");
8
+ const submitOrder_1 = require("./orders/submitOrder");
8
9
  const terminal = protocol_1.Terminal.fromNodeEnv();
9
10
  (0, data_order_1.provideOrderActionsWithCredential)(terminal, 'BINANCE', {
10
11
  type: 'object',
@@ -16,6 +17,7 @@ const terminal = protocol_1.Terminal.fromNodeEnv();
16
17
  }, {
17
18
  submitOrder: submitOrder_1.submitOrder,
18
19
  cancelOrder: cancelOrder_1.cancelOrder,
20
+ modifyOrder: modifyOrder_1.modifyOrder,
19
21
  listOrders: listOrders_1.listOrders,
20
22
  });
21
23
  //# sourceMappingURL=order-actions-with-credential.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"order-actions-with-credential.js","sourceRoot":"","sources":["../../src/services/order-actions-with-credential.ts"],"names":[],"mappings":";;AAAA,mDAAuE;AACvE,+CAA4C;AAE5C,sDAAmD;AACnD,sDAAmD;AACnD,oDAAiD;AAEjD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,IAAA,8CAAiC,EAC/B,QAAQ,EACR,SAAS,EACT;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACtC,UAAU,EAAE;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/B;CACF,EACD;IACE,WAAW,EAAX,yBAAW;IACX,WAAW,EAAX,yBAAW;IACX,UAAU,EAAV,uBAAU;CACX,CACF,CAAC","sourcesContent":["import { provideOrderActionsWithCredential } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { ICredential } from '../api/private-api';\nimport { submitOrder } from './orders/submitOrder';\nimport { cancelOrder } from './orders/cancelOrder';\nimport { listOrders } from './orders/listOrders';\n\nconst terminal = Terminal.fromNodeEnv();\n\nprovideOrderActionsWithCredential<ICredential>(\n terminal,\n 'BINANCE',\n {\n type: 'object',\n required: ['access_key', 'secret_key'],\n properties: {\n access_key: { type: 'string' },\n secret_key: { type: 'string' },\n },\n },\n {\n submitOrder,\n cancelOrder,\n listOrders,\n },\n);\n"]}
1
+ {"version":3,"file":"order-actions-with-credential.js","sourceRoot":"","sources":["../../src/services/order-actions-with-credential.ts"],"names":[],"mappings":";;AAAA,mDAAuE;AACvE,+CAA4C;AAE5C,sDAAmD;AACnD,oDAAiD;AACjD,sDAAmD;AACnD,sDAAmD;AAEnD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,IAAA,8CAAiC,EAC/B,QAAQ,EACR,SAAS,EACT;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;IACtC,UAAU,EAAE;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/B;CACF,EACD;IACE,WAAW,EAAX,yBAAW;IACX,WAAW,EAAX,yBAAW;IACX,WAAW,EAAX,yBAAW;IACX,UAAU,EAAV,uBAAU;CACX,CACF,CAAC","sourcesContent":["import { provideOrderActionsWithCredential } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { ICredential } from '../api/private-api';\nimport { cancelOrder } from './orders/cancelOrder';\nimport { listOrders } from './orders/listOrders';\nimport { modifyOrder } from './orders/modifyOrder';\nimport { submitOrder } from './orders/submitOrder';\n\nconst terminal = Terminal.fromNodeEnv();\n\nprovideOrderActionsWithCredential<ICredential>(\n terminal,\n 'BINANCE',\n {\n type: 'object',\n required: ['access_key', 'secret_key'],\n properties: {\n access_key: { type: 'string' },\n secret_key: { type: 'string' },\n },\n },\n {\n submitOrder,\n cancelOrder,\n modifyOrder,\n listOrders,\n },\n);\n"]}
@@ -0,0 +1,4 @@
1
+ import { IActionHandlerOfModifyOrder } from '@yuants/data-order';
2
+ import { ICredential } from '../../api/private-api';
3
+ export declare const modifyOrder: IActionHandlerOfModifyOrder<ICredential>;
4
+ //# sourceMappingURL=modifyOrder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modifyOrder.d.ts","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,WAAW,EAA0C,MAAM,uBAAuB,CAAC;AA4D5F,eAAO,MAAM,WAAW,EAAE,2BAA2B,CAAC,WAAW,CAQhE,CAAC"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.modifyOrder = void 0;
4
+ const client_1 = require("../../api/client");
5
+ const private_api_1 = require("../../api/private-api");
6
+ const order_utils_1 = require("./order-utils");
7
+ const modifyUnifiedOrder = async (credential, order) => {
8
+ const symbol = (0, order_utils_1.decodeFutureSymbol)(order.product_id);
9
+ const side = (0, order_utils_1.mapOrderDirectionToSide)(order.order_direction);
10
+ const res = await (0, private_api_1.putUmOrder)(credential, {
11
+ symbol,
12
+ side,
13
+ orderId: order.order_id ? parseInt(order.order_id) : undefined,
14
+ // origClientOrderId: order.client_order_id, // TODO: support client_order_id
15
+ quantity: order.volume,
16
+ price: order.price,
17
+ });
18
+ if ((0, client_1.isApiError)(res)) {
19
+ throw new Error(`Binance modify unified order failed: ${res.code} ${res.msg}`);
20
+ }
21
+ };
22
+ const modifySpotOrder = async (credential, order) => {
23
+ const symbol = (0, order_utils_1.decodeSpotSymbol)(order.product_id);
24
+ const side = (0, order_utils_1.mapOrderDirectionToSide)(order.order_direction);
25
+ const type = (0, order_utils_1.mapOrderTypeToOrdType)(order.order_type);
26
+ const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;
27
+ const params = {
28
+ symbol,
29
+ side,
30
+ type,
31
+ cancelReplaceMode: 'STOP_ON_FAILURE',
32
+ cancelOrderId: order.order_id ? parseInt(order.order_id) : undefined,
33
+ // cancelOrigClientOrderId: order.client_order_id, // TODO: support client_order_id
34
+ newClientOrderId: (0, order_utils_1.deriveClientOrderId)(order),
35
+ quantity: order.volume,
36
+ };
37
+ if (type === 'LIMIT') {
38
+ if (order.price === undefined) {
39
+ throw new Error('Binance spot LIMIT order requires price');
40
+ }
41
+ params.price = order.price;
42
+ params.timeInForce = timeInForce;
43
+ }
44
+ if (order.price !== undefined && type === 'MARKET') {
45
+ params.price = order.price;
46
+ }
47
+ const res = await (0, private_api_1.postSpotOrderCancelReplace)(credential, params);
48
+ if ((0, client_1.isApiError)(res)) {
49
+ throw new Error(`Binance modify spot order failed: ${res.code} ${res.msg}`);
50
+ }
51
+ };
52
+ const modifyOrder = async (credential, order) => {
53
+ if (order.account_id.includes('/unified/')) {
54
+ return modifyUnifiedOrder(credential, order);
55
+ }
56
+ if (order.account_id.includes('/spot/')) {
57
+ return modifySpotOrder(credential, order);
58
+ }
59
+ throw new Error(`Unsupported account_id for modifyOrder: ${order.account_id}`);
60
+ };
61
+ exports.modifyOrder = modifyOrder;
62
+ //# sourceMappingURL=modifyOrder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modifyOrder.js","sourceRoot":"","sources":["../../../src/services/orders/modifyOrder.ts"],"names":[],"mappings":"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","sourcesContent":["import { IActionHandlerOfModifyOrder } from '@yuants/data-order';\nimport { isApiError } from '../../api/client';\nimport { ICredential, postSpotOrderCancelReplace, putUmOrder } from '../../api/private-api';\nimport {\n decodeFutureSymbol,\n decodeSpotSymbol,\n deriveClientOrderId,\n mapOrderDirectionToSide,\n mapOrderTypeToOrdType,\n} from './order-utils';\n\nconst modifyUnifiedOrder: IActionHandlerOfModifyOrder<ICredential> = async (credential, order) => {\n const symbol = decodeFutureSymbol(order.product_id);\n const side = mapOrderDirectionToSide(order.order_direction);\n\n const res = await putUmOrder(credential, {\n symbol,\n side,\n orderId: order.order_id ? parseInt(order.order_id) : undefined,\n // origClientOrderId: order.client_order_id, // TODO: support client_order_id\n quantity: order.volume,\n price: order.price,\n });\n if (isApiError(res)) {\n throw new Error(`Binance modify unified order failed: ${res.code} ${res.msg}`);\n }\n};\n\nconst modifySpotOrder: IActionHandlerOfModifyOrder<ICredential> = async (credential, order) => {\n const symbol = decodeSpotSymbol(order.product_id);\n const side = mapOrderDirectionToSide(order.order_direction);\n const type = mapOrderTypeToOrdType(order.order_type);\n const timeInForce = order.order_type === 'MAKER' ? 'GTX' : order.order_type === 'LIMIT' ? 'GTC' : undefined;\n\n const params: Parameters<typeof postSpotOrderCancelReplace>[1] = {\n symbol,\n side,\n type,\n cancelReplaceMode: 'STOP_ON_FAILURE',\n cancelOrderId: order.order_id ? parseInt(order.order_id) : undefined,\n // cancelOrigClientOrderId: order.client_order_id, // TODO: support client_order_id\n newClientOrderId: deriveClientOrderId(order),\n quantity: order.volume,\n };\n\n if (type === 'LIMIT') {\n if (order.price === undefined) {\n throw new Error('Binance spot LIMIT order requires price');\n }\n params.price = order.price;\n params.timeInForce = timeInForce;\n }\n if (order.price !== undefined && type === 'MARKET') {\n params.price = order.price;\n }\n\n const res = await postSpotOrderCancelReplace(credential, params);\n if (isApiError(res)) {\n throw new Error(`Binance modify spot order failed: ${res.code} ${res.msg}`);\n }\n};\n\nexport const modifyOrder: IActionHandlerOfModifyOrder<ICredential> = async (credential, order) => {\n if (order.account_id.includes('/unified/')) {\n return modifyUnifiedOrder(credential, order);\n }\n if (order.account_id.includes('/spot/')) {\n return modifySpotOrder(credential, order);\n }\n throw new Error(`Unsupported account_id for modifyOrder: ${order.account_id}`);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-binance",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "dist",
@@ -1,31 +1,33 @@
1
1
  {
2
2
  "apps/vendor-binance/AGENTS.md": "378369925bffa237cd5e8ef459fe2bc2a141337c",
3
- "apps/vendor-binance/CHANGELOG.json": "24e2317dab377b165cd974e32a76ca077a73afbc",
4
- "apps/vendor-binance/CHANGELOG.md": "4306dd57f2c9103faa60bd5f0ed399a067d295d7",
3
+ "apps/vendor-binance/CHANGELOG.json": "6221819d12c07307d4cc62ed85bf226773ed3733",
4
+ "apps/vendor-binance/CHANGELOG.md": "e2388bde3ed2b3d56c723466509e8aab3f46c210",
5
5
  "apps/vendor-binance/README.md": "4ab94c08b3d07398aee74c3264a4f87d554d20fa",
6
- "apps/vendor-binance/SESSION_NOTES.md": "14ffb6e43fda6b0b4f8d577781563884a8026f15",
6
+ "apps/vendor-binance/SESSION_NOTES.md": "d69fb3d14517d838b99985f2b82b35e81ba436b3",
7
7
  "apps/vendor-binance/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
8
8
  "apps/vendor-binance/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
9
9
  "apps/vendor-binance/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
10
10
  "apps/vendor-binance/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
11
11
  "apps/vendor-binance/etc/vendor-binance.api.md": "2094b84e9b5e7503f5c42b31fffee8d7db47fe7b",
12
- "apps/vendor-binance/package.json": "dc730e729df795fc316cb726f820fd486af79d5c",
12
+ "apps/vendor-binance/package.json": "9f70b3f5122cf464855f032d0732cd0f175ce1c5",
13
13
  "apps/vendor-binance/src/api/client.ts": "bce65e7525e12ac6ecfb69899f5ed2056ee80404",
14
- "apps/vendor-binance/src/api/private-api.ts": "1c858f64fa8b498a453dd39b2f808c7b3f6b1cdd",
15
- "apps/vendor-binance/src/api/public-api.ts": "a1ba3d006c6ebca42fda068dc3bcbf604984a917",
14
+ "apps/vendor-binance/src/api/private-api.ts": "e7643bd482e4d8f4eefe39aee578e5ea52094b2b",
15
+ "apps/vendor-binance/src/api/public-api.ts": "04671c8732103fac9267c4133a8b96642452daa9",
16
16
  "apps/vendor-binance/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
17
- "apps/vendor-binance/src/index.ts": "30281e0e54ae7528487ae0808d15f4c560f383a2",
18
- "apps/vendor-binance/src/interest_rate.ts": "dd7f7d529e4916fa3d50cafaff3bd99e2a8b3533",
17
+ "apps/vendor-binance/src/index.ts": "50cef2ecce48b30f38bf67728cf1b13afadf9e69",
19
18
  "apps/vendor-binance/src/legacy_index.ts": "0b56f9a9d4d34ca0a136d267e03ae984b86d8149",
20
- "apps/vendor-binance/src/product.ts": "78d38412464870975ff74f7d20bbf2b1b6796127",
21
- "apps/vendor-binance/src/quote.ts": "37ff0ab9b1521fa2d2e6e9187a43a89df361d802",
19
+ "apps/vendor-binance/src/public-data/interest_rate.ts": "5707961027cfc8be32dd40263ca075c2068535bb",
20
+ "apps/vendor-binance/src/public-data/ohlc.ts": "bbc2a939865537f0db0089d43b5cc1b7dff7f348",
21
+ "apps/vendor-binance/src/public-data/product.ts": "6fcc1e8cbcba7e5e21b821552f883ef11b7672e1",
22
+ "apps/vendor-binance/src/public-data/quote.ts": "5ca12fa16733ccd09ac033082ce91763c88f5843",
22
23
  "apps/vendor-binance/src/services/account-actions-with-credential.ts": "0f53b961fc5885deaca1c5776e82a95f5acd9917",
23
24
  "apps/vendor-binance/src/services/accounts/profile.ts": "63205996e6525d103d1829814e04f7a352e15541",
24
25
  "apps/vendor-binance/src/services/accounts/spot.ts": "3c2826d454a94ad519dd4183ef4bb45a9840f75a",
25
26
  "apps/vendor-binance/src/services/accounts/unified.ts": "0d4103dc3f9a5ce171872f5d5a2758a3307dde53",
26
- "apps/vendor-binance/src/services/order-actions-with-credential.ts": "dc6caeffcbdecb9bc20404463a87133a196e0c5e",
27
+ "apps/vendor-binance/src/services/order-actions-with-credential.ts": "d7ea63781f6c4d3a47e453a48935692c3c9e761d",
27
28
  "apps/vendor-binance/src/services/orders/cancelOrder.ts": "44b6f87bca28108e0aebe4ef469172ba0c86b402",
28
29
  "apps/vendor-binance/src/services/orders/listOrders.ts": "b81b8de6a20de37a692a57569b93bdfb9b96a9ed",
30
+ "apps/vendor-binance/src/services/orders/modifyOrder.ts": "7260834300a269c2122e27cfc7ef4ad954fa3a17",
29
31
  "apps/vendor-binance/src/services/orders/order-utils.ts": "04f6af66ecaba2d405cb6791bf64412fabc64d0d",
30
32
  "apps/vendor-binance/src/services/orders/submitOrder.ts": "2d6a9ed669d1d6922d3b496d566d23ed63dc403f",
31
33
  "apps/vendor-binance/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
@@ -1,55 +0,0 @@
1
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
2
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
3
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
4
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
5
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
6
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
7
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
8
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
9
- function fulfill(value) { resume("next", value); }
10
- function reject(value) { resume("throw", value); }
11
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
12
- };
13
- import { createSeriesProvider } from '@yuants/data-series';
14
- import { Terminal } from '@yuants/protocol';
15
- import { decodePath, formatTime } from '@yuants/utils';
16
- import { firstValueFrom, timer } from 'rxjs';
17
- import { getFutureFundingRate } from './api/public-api';
18
- const terminal = Terminal.fromNodeEnv();
19
- createSeriesProvider(terminal, {
20
- tableName: 'interest_rate',
21
- series_id_prefix_parts: ['BINANCE'],
22
- reversed: true,
23
- serviceOptions: { concurrent: 1 },
24
- queryFn: function ({ series_id, started_at, ended_at }) {
25
- return __asyncGenerator(this, arguments, function* () {
26
- const [datasource_id, product_id] = decodePath(series_id);
27
- let current_start = started_at;
28
- const [instType, symbol] = decodePath(product_id);
29
- while (true) {
30
- // 向前翻页,时间降序
31
- const res = yield __await(getFutureFundingRate({
32
- symbol: symbol,
33
- startTime: current_start,
34
- endTime: ended_at,
35
- limit: 1000,
36
- }));
37
- yield yield __await(res.map((v) => ({
38
- series_id,
39
- created_at: formatTime(v.fundingTime),
40
- datasource_id,
41
- product_id,
42
- long_rate: `${-v.fundingRate}`,
43
- short_rate: `${v.fundingRate}`,
44
- settlement_price: '',
45
- })));
46
- if (res.length < 1000) {
47
- break;
48
- }
49
- current_start = +res[res.length - 1].fundingTime;
50
- yield __await(firstValueFrom(timer(1000)));
51
- }
52
- });
53
- },
54
- });
55
- //# sourceMappingURL=interest_rate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,oBAAoB,CAAgB,QAAQ,EAAE;IAC5C,SAAS,EAAE,eAAe;IAC1B,sBAAsB,EAAE,CAAC,SAAS,CAAC;IACnC,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;IACjC,OAAO,EAAE,UAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;;YAC3D,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,aAAa,GAAG,UAAU,CAAC;YAC/B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;YAClD,OAAO,IAAI,EAAE;gBACX,YAAY;gBACZ,MAAM,GAAG,GAAG,cAAM,oBAAoB,CAAC;oBACrC,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,aAAa;oBACxB,OAAO,EAAE,QAAQ;oBACjB,KAAK,EAAE,IAAI;iBACZ,CAAC,CAAA,CAAC;gBACH,oBAAM,GAAG,CAAC,GAAG,CACX,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC;oBACrB,SAAS;oBACT,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;oBACrC,aAAa;oBACb,UAAU;oBACV,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE;oBAC9B,UAAU,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;oBAC9B,gBAAgB,EAAE,EAAE;iBACrB,CAAC,CACH,CAAA,CAAC;gBACF,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,EAAE;oBACrB,MAAM;iBACP;gBACD,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;gBACjD,cAAM,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA,CAAC;aACnC;QACH,CAAC;KAAA;CACF,CAAC,CAAC","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { decodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, timer } from 'rxjs';\nimport { getFutureFundingRate } from './api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\ncreateSeriesProvider<IInterestRate>(terminal, {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['BINANCE'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const [datasource_id, product_id] = decodePath(series_id);\n let current_start = started_at;\n const [instType, symbol] = decodePath(product_id);\n while (true) {\n // 向前翻页,时间降序\n const res = await getFutureFundingRate({\n symbol: symbol,\n startTime: current_start,\n endTime: ended_at,\n limit: 1000,\n });\n yield res.map(\n (v): IInterestRate => ({\n series_id,\n created_at: formatTime(v.fundingTime),\n datasource_id,\n product_id,\n long_rate: `${-v.fundingRate}`,\n short_rate: `${v.fundingRate}`,\n settlement_price: '',\n }),\n );\n if (res.length < 1000) {\n break;\n }\n current_start = +res[res.length - 1].fundingTime;\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,oDAAoD;AACpD,MAAM,KAAK,GAAG,2BAA2B,CACvC,QAAQ,EACR,SAAS,EACT,KAAK,EAAE,GAA0B,EAAuB,EAAE;IACxD,sDAAsD;IACtD,MAAM,YAAY,GAAG,MAAM,qBAAqB,EAAE,CAAC;IAEnD,qCAAqC;IACrC,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAY,EAAE;QACnD,OAAO;YACL,aAAa,EAAE,SAAS;YACxB,UAAU,EAAE,UAAU,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;YACpD,aAAa,EAAE,MAAM,CAAC,SAAS;YAC/B,cAAc,EAAE,MAAM,CAAC,UAAU;YACjC,UAAU,EAAE,CAAC,MAAM,MAAM,CAAC,cAAc,EAAE;YAC1C,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC,MAAM,MAAM,CAAC,iBAAiB,EAAE;YAC9C,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,OAAO;YACrD,gBAAgB,EAAE,EAAE;YACpB,WAAW,EAAE,CAAC,MAAM,CAAC,qBAAqB,GAAG,GAAG;YAChD,gBAAgB,EAAE,CAAC;YACnB,iBAAiB,EAAE,CAAC;YACpB,YAAY,EAAE,CAAC;YACf,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,qBAAqB;YAChC,gBAAgB,EAAE,KAAK;SACxB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,EACD;IACE,qBAAqB,EAAE,OAAQ;CAChC,CACF,CAAC","sourcesContent":["import { IProduct, IQueryProductsRequest, provideQueryProductsService } from '@yuants/data-product';\nimport { Terminal } from '@yuants/protocol';\nimport { encodePath } from '@yuants/utils';\nimport { getFutureExchangeInfo } from './api/public-api';\n\nconst terminal = Terminal.fromNodeEnv();\n\n// Provide QueryProducts service with the new design\nconst cache = provideQueryProductsService(\n terminal,\n 'BINANCE',\n async (req: IQueryProductsRequest): Promise<IProduct[]> => {\n // Directly call the external API to get exchange info\n const exchangeInfo = await getFutureExchangeInfo();\n\n // Convert symbols to IProduct format\n return exchangeInfo.symbols.map((symbol): IProduct => {\n return {\n datasource_id: 'BINANCE',\n product_id: encodePath('usdt-future', symbol.symbol),\n base_currency: symbol.baseAsset,\n quote_currency: symbol.quoteAsset,\n price_step: +`1e-${symbol.pricePrecision}`,\n value_scale: 1,\n volume_step: +`1e-${symbol.quantityPrecision}`,\n name: `${symbol.baseAsset}/${symbol.quoteAsset} PERP`,\n value_scale_unit: '',\n margin_rate: +symbol.requiredMarginPercent / 100,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n market_id: 'BINANCE/USDT-FUTURE',\n no_interest_rate: false,\n };\n });\n },\n {\n auto_refresh_interval: 3600_000,\n },\n);\n"]}