@yuants/app-virtual-exchange 0.18.11 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credential.js +25 -18
- package/dist/credential.js.map +1 -1
- package/dist/general.js.map +1 -1
- package/dist/series-collector/interest-ledger.js +143 -0
- package/dist/series-collector/interest-ledger.js.map +1 -0
- package/dist/series-collector/patch-interest-rate.js +2 -23
- package/dist/series-collector/patch-interest-rate.js.map +1 -1
- package/dist/series-collector/patch-ohlc.js +2 -23
- package/dist/series-collector/patch-ohlc.js.map +1 -1
- package/dist/series-collector/setup.js +4 -12
- package/dist/series-collector/setup.js.map +1 -1
- package/dist/series-collector/sql-helpers.js +27 -0
- package/dist/series-collector/sql-helpers.js.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/lib/credential.d.ts +14 -4
- package/lib/credential.d.ts.map +1 -1
- package/lib/credential.js +27 -19
- package/lib/credential.js.map +1 -1
- package/lib/general.js.map +1 -1
- package/lib/series-collector/interest-ledger.d.ts +16 -0
- package/lib/series-collector/interest-ledger.d.ts.map +1 -0
- package/lib/series-collector/interest-ledger.js +152 -0
- package/lib/series-collector/interest-ledger.js.map +1 -0
- package/lib/series-collector/patch-interest-rate.d.ts.map +1 -1
- package/lib/series-collector/patch-interest-rate.js +2 -23
- package/lib/series-collector/patch-interest-rate.js.map +1 -1
- package/lib/series-collector/patch-ohlc.d.ts.map +1 -1
- package/lib/series-collector/patch-ohlc.js +2 -23
- package/lib/series-collector/patch-ohlc.js.map +1 -1
- package/lib/series-collector/setup.js +4 -12
- package/lib/series-collector/setup.js.map +1 -1
- package/lib/series-collector/sql-helpers.d.ts +6 -0
- package/lib/series-collector/sql-helpers.d.ts.map +1 -1
- package/lib/series-collector/sql-helpers.js +31 -1
- package/lib/series-collector/sql-helpers.js.map +1 -1
- package/lib/types.d.ts +5 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/package.json +6 -6
- package/temp/build/typescript/ts_KjrfbUqK.json +1 -1
- package/temp/test/jest/haste-map-76b16e3ab892e2fd05068740b7223d57-a6c52f003baf5bf33cffc52364f3bd7a-4ce9ff2cd20d69bbaecd1543c7e32e02 +0 -0
- package/temp/test/jest/perf-cache-76b16e3ab892e2fd05068740b7223d57-da39a3ee5e6b4b0d3255bfef95601890 +1 -1
package/lib/credential.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAqB9C,eAAO,MAAM,eAAe;UAiEhB,MAAM;gBACA,mBAAmB,GAAG,IAAI;kBACxB,MAAM,GAAG,IAAI;WACpB,GAAG;IA/DwD,CAAC;AAEzE,eAAO,MAAM,6BAA6B;UA0D9B,MAAM;gBACA,mBAAmB,GAAG,IAAI;kBACxB,MAAM,GAAG,IAAI;WACpB,GAAG;KA1Df,CAAC;AAEF,eAAO,MAAM,iBAAiB,6DAY7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,qCAQjC,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAU,cAAc,MAAM,oDAIrE,CAAC;AA6EF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAAU,MAAM,MAAM;;;;EAMzD,CAAC"}
|
package/lib/credential.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCredentialBySecretId = exports.validCredentialTypes$ = exports.validCredentials$ = void 0;
|
|
3
|
+
exports.getCredentialBySecretId = exports.getCredentialByCredentialId = exports.validCredentialTypes$ = exports.validCredentials$ = exports.mapCredentialIdToCredentials$ = exports.allCredentials$ = void 0;
|
|
4
4
|
const cache_1 = require("@yuants/cache");
|
|
5
5
|
const exchange_1 = require("@yuants/exchange");
|
|
6
6
|
const protocol_1 = require("@yuants/protocol");
|
|
@@ -25,6 +25,32 @@ const secretSignToCredentialIdCache = (0, cache_1.createCache)(async (sign) => {
|
|
|
25
25
|
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
26
26
|
return credential;
|
|
27
27
|
});
|
|
28
|
+
exports.allCredentials$ = (0, rxjs_1.defer)(() => terminal.client.requestForResponseData('VEX/ListExchangeCredential', {})).pipe((0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.shareReplay)(1));
|
|
29
|
+
exports.mapCredentialIdToCredentials$ = exports.allCredentials$.pipe((0, rxjs_1.map)((x) => Map.groupBy(x, (item) => item.credentialId || '')), (0, rxjs_1.shareReplay)(1));
|
|
30
|
+
exports.validCredentials$ = exports.allCredentials$.pipe((0, rxjs_1.map)((x) => {
|
|
31
|
+
const map = new Map();
|
|
32
|
+
if (!x)
|
|
33
|
+
return map;
|
|
34
|
+
for (const xx of x) {
|
|
35
|
+
if (xx.credentialId && xx.credential) {
|
|
36
|
+
map.set(xx.credentialId, xx.credential);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return map;
|
|
40
|
+
}), (0, rxjs_1.shareReplay)(1));
|
|
41
|
+
exports.validCredentialTypes$ = exports.validCredentials$.pipe((0, rxjs_1.map)((credentials) => {
|
|
42
|
+
const types = new Set();
|
|
43
|
+
credentials.forEach((credential) => {
|
|
44
|
+
types.add(credential.type);
|
|
45
|
+
});
|
|
46
|
+
return Array.from(types);
|
|
47
|
+
}));
|
|
48
|
+
const getCredentialByCredentialId = async (credentialId) => {
|
|
49
|
+
const credentials = (await (0, rxjs_1.firstValueFrom)(exports.mapCredentialIdToCredentials$)).get(credentialId);
|
|
50
|
+
const theCredential = credentials === null || credentials === void 0 ? void 0 : credentials[0].credential;
|
|
51
|
+
return theCredential;
|
|
52
|
+
};
|
|
53
|
+
exports.getCredentialByCredentialId = getCredentialByCredentialId;
|
|
28
54
|
/**
|
|
29
55
|
* 根据 credential 信息解析出对应的 credential ID
|
|
30
56
|
* 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销
|
|
@@ -81,24 +107,6 @@ terminal.server.provideService('VEX/ListCredentials', {}, async () => {
|
|
|
81
107
|
const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
|
|
82
108
|
return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
|
|
83
109
|
});
|
|
84
|
-
exports.validCredentials$ = (0, rxjs_1.defer)(() => listAllCredentials()).pipe((0, rxjs_1.map)((x) => {
|
|
85
|
-
const map = new Map();
|
|
86
|
-
if (!x)
|
|
87
|
-
return map;
|
|
88
|
-
for (const xx of x) {
|
|
89
|
-
if (xx.credentialId && xx.credential) {
|
|
90
|
-
map.set(xx.credentialId, xx.credential);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return map;
|
|
94
|
-
}), (0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.shareReplay)(1));
|
|
95
|
-
exports.validCredentialTypes$ = exports.validCredentials$.pipe((0, rxjs_1.map)((credentials) => {
|
|
96
|
-
const types = new Set();
|
|
97
|
-
credentials.forEach((credential) => {
|
|
98
|
-
types.add(credential.type);
|
|
99
|
-
});
|
|
100
|
-
return Array.from(types);
|
|
101
|
-
}));
|
|
102
110
|
/**
|
|
103
111
|
* 根据 secret sign 解析出对应的 credential 以及 credential ID
|
|
104
112
|
* @param sign - secret sign
|
package/lib/credential.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, listSecrets, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\nexport interface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst credentialReader = process.env.NODE_UNIT_PUBLIC_KEY || terminal.keyPair.public_key;\n\n/**\n * 根据 secret sign 解析出对应的 exchange credential\n * 此处可以做缓存,因为同一个 secret sign 对应的 credential 信息永远不会变化,可以节约解密和后续 SQL 查询的开销\n * 得到 credential 后,此 credential 不一定是有效的,因为可能凭证信息已经过期或被撤销\n */\nconst secretSignToCredentialIdCache = createCache(async (sign: string) => {\n const sql = `SELECT * FROM secret WHERE sign = ${escapeSQL(sign)} LIMIT 1;`;\n const res = await requestSQL<ISecret[]>(terminal, sql);\n if (res.length === 0) throw newError('SECRET_NOT_FOUND', { sign });\n const secret = res[0];\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n return credential;\n});\n\n/**\n * 根据 credential 信息解析出对应的 credential ID\n * 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销\n * 但是需要注意的是,credential ID 可能会因为凭证被撤销而失效,但是可以在下游调用其他服务时感知到,因此可以永久缓存\n */\nconst credentialIdCache = createCache(async (credentialKey: string) => {\n const credential = JSON.parse(credentialKey) as IExchangeCredential;\n const res = await getCredentialId(terminal, credential);\n return res.data;\n});\n\nconst listAllCredentials = async () => {\n const secrets = await listSecrets(terminal, {\n reader: credentialReader,\n tags: { type: 'exchange_credential' },\n });\n\n const results = await Promise.allSettled(secrets.map((secret) => getCredentialBySecretId(secret.sign)));\n return results.map(\n (\n result,\n index,\n ): {\n sign: string;\n credential: IExchangeCredential | null;\n credentialId: string | null;\n error: any;\n } => {\n if (result.status === 'fulfilled') {\n return {\n sign: secrets[index].sign,\n credential: result.value.credential,\n credentialId: result.value.credentialId,\n error: null,\n };\n } else {\n return {\n sign: secrets[index].sign,\n credential: null,\n credentialId: null,\n error: `${result.reason}`,\n };\n }\n },\n );\n};\n\nterminal.server.provideService<IExchangeCredential, ISecret>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n const secret = await writeSecret(terminal, credentialReader, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK', data: secret } };\n },\n);\n\n// For Debugging Purpose\nterminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n});\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n if (!x) return map;\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const validCredentialTypes$ = validCredentials$.pipe(\n map((credentials) => {\n const types = new Set<string>();\n credentials.forEach((credential) => {\n types.add(credential.type);\n });\n return Array.from(types);\n }),\n);\n\n/**\n * 根据 secret sign 解析出对应的 credential 以及 credential ID\n * @param sign - secret sign\n * @returns 解析得到的 credential 以及对应的 credential ID\n * @throws 如果无法解析出对应的 credential 或 credential ID,则抛出异常\n *\n * 不依赖 List Credential 服务,可以及时感知凭证的新增和变更\n */\nexport const getCredentialBySecretId = async (sign: string) => {\n const credential = await secretSignToCredentialIdCache.query(sign);\n if (!credential) throw newError('CREDENTIAL_NOT_RESOLVED', { sign });\n const credentialId = await credentialIdCache.query(JSON.stringify(credential));\n if (!credentialId) throw newError('CREDENTIAL_ID_NOT_RESOLVED', { sign });\n return { sign, credential, credentialId };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, listSecrets, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { newError } from '@yuants/utils';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\nimport { IExchangeCredential } from './types';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst credentialReader = process.env.NODE_UNIT_PUBLIC_KEY || terminal.keyPair.public_key;\n\n/**\n * 根据 secret sign 解析出对应的 exchange credential\n * 此处可以做缓存,因为同一个 secret sign 对应的 credential 信息永远不会变化,可以节约解密和后续 SQL 查询的开销\n * 得到 credential 后,此 credential 不一定是有效的,因为可能凭证信息已经过期或被撤销\n */\nconst secretSignToCredentialIdCache = createCache(async (sign: string) => {\n const sql = `SELECT * FROM secret WHERE sign = ${escapeSQL(sign)} LIMIT 1;`;\n const res = await requestSQL<ISecret[]>(terminal, sql);\n if (res.length === 0) throw newError('SECRET_NOT_FOUND', { sign });\n const secret = res[0];\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n return credential;\n});\n\nexport const allCredentials$ = defer(() =>\n terminal.client.requestForResponseData<{}, Awaited<ReturnType<typeof listAllCredentials>>>(\n 'VEX/ListExchangeCredential',\n {},\n ),\n).pipe(repeat({ delay: 10000 }), retry({ delay: 5000 }), shareReplay(1));\n\nexport const mapCredentialIdToCredentials$ = allCredentials$.pipe(\n map((x) => Map.groupBy(x, (item) => item.credentialId || '')),\n shareReplay(1),\n);\n\nexport const validCredentials$ = allCredentials$.pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n if (!x) return map;\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n shareReplay(1),\n);\n\nexport const validCredentialTypes$ = validCredentials$.pipe(\n map((credentials) => {\n const types = new Set<string>();\n credentials.forEach((credential) => {\n types.add(credential.type);\n });\n return Array.from(types);\n }),\n);\n\nexport const getCredentialByCredentialId = async (credentialId: string) => {\n const credentials = (await firstValueFrom(mapCredentialIdToCredentials$)).get(credentialId);\n const theCredential = credentials?.[0].credential;\n return theCredential;\n};\n\n/**\n * 根据 credential 信息解析出对应的 credential ID\n * 此处可以做缓存,因为同一个 credential 永远对应同一个 credential ID,可以节约后续 SQL 查询的开销\n * 但是需要注意的是,credential ID 可能会因为凭证被撤销而失效,但是可以在下游调用其他服务时感知到,因此可以永久缓存\n */\nconst credentialIdCache = createCache(async (credentialKey: string) => {\n const credential = JSON.parse(credentialKey) as IExchangeCredential;\n const res = await getCredentialId(terminal, credential);\n return res.data;\n});\n\nconst listAllCredentials = async () => {\n const secrets = await listSecrets(terminal, {\n reader: credentialReader,\n tags: { type: 'exchange_credential' },\n });\n\n const results = await Promise.allSettled(secrets.map((secret) => getCredentialBySecretId(secret.sign)));\n return results.map(\n (\n result,\n index,\n ): {\n sign: string;\n credential: IExchangeCredential | null;\n credentialId: string | null;\n error: any;\n } => {\n if (result.status === 'fulfilled') {\n return {\n sign: secrets[index].sign,\n credential: result.value.credential,\n credentialId: result.value.credentialId,\n error: null,\n };\n } else {\n return {\n sign: secrets[index].sign,\n credential: null,\n credentialId: null,\n error: `${result.reason}`,\n };\n }\n },\n );\n};\n\nterminal.server.provideService<IExchangeCredential, ISecret>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n const secret = await writeSecret(terminal, credentialReader, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK', data: secret } };\n },\n);\n\n// For Debugging Purpose\nterminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n});\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\n/**\n * 根据 secret sign 解析出对应的 credential 以及 credential ID\n * @param sign - secret sign\n * @returns 解析得到的 credential 以及对应的 credential ID\n * @throws 如果无法解析出对应的 credential 或 credential ID,则抛出异常\n *\n * 不依赖 List Credential 服务,可以及时感知凭证的新增和变更\n */\nexport const getCredentialBySecretId = async (sign: string) => {\n const credential = await secretSignToCredentialIdCache.query(sign);\n if (!credential) throw newError('CREDENTIAL_NOT_RESOLVED', { sign });\n const credentialId = await credentialIdCache.query(JSON.stringify(credential));\n if (!credentialId) throw newError('CREDENTIAL_ID_NOT_RESOLVED', { sign });\n return { sign, credential, credentialId };\n};\n"]}
|
package/lib/general.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":";;AAEA,+CAAkG;AAClG,+CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { getCredentialBySecretId } from './credential';\nimport { polyfillOrders, polyfillPosition } from './position';\nimport { IExchangeCredential } from './types';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IPosition[]>(\n 'VEX/GetPositions',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getPositions(terminal, credential.credential, msg.req.product_id);\n if (!res.data) return { res };\n const positions = await polyfillPosition(res.data);\n positions.forEach((pos) => {\n pos.account_id = credential.credentialId;\n });\n return { res: { code: 0, message: 'OK', data: positions } };\n },\n);\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IOrder[]>(\n 'VEX/GetOrders',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getOrders(terminal, credential.credential, msg.req.product_id);\n if (!res.data) return { res };\n const orders = res.data;\n orders.forEach((order) => {\n order.account_id = credential.credentialId;\n });\n await polyfillOrders(orders);\n return { res: { code: 0, message: 'OK', data: orders } };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, { order_id: string }>(\n 'VEX/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const [order] = await polyfillOrders([msg.req.order]);\n const res = await submitOrder(terminal, credential.credential, order);\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const [order] = await polyfillOrders([msg.req.order]);\n const res = await modifyOrder(terminal, credential.credential, order);\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/CancelOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const [order] = await polyfillOrders([msg.req.order]);\n const res = await cancelOrder(terminal, credential.credential, order);\n return { res };\n },\n);\n\n// GetCredential\nterminal.server.provideService<\n { secret_id: string },\n {\n sign: string;\n credential: IExchangeCredential;\n credentialId: string;\n }\n>(\n 'VEX/GetCredential',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n return {\n res: {\n code: 0,\n message: 'OK',\n data: credential,\n },\n };\n },\n);\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const listInterestLedgerSeriesIds: () => Promise<Map<string, "backward" | "forward">>;
|
|
2
|
+
export declare const encodeInterestLedgerSeriesId: (account_id: string, ledger_type: string) => string;
|
|
3
|
+
export declare const decodeInterestLedgerSeriesId: (series_id: string) => {
|
|
4
|
+
account_id: string;
|
|
5
|
+
ledger_type: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const handleIngestInterestLedgerForward: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
|
|
8
|
+
export declare const handleIngestInterestLedgerBackward: (series_id: string, direction: "forward" | "backward") => Promise<void>;
|
|
9
|
+
export declare const handleIngestInterestLedgerPatch: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
|
|
10
|
+
export declare const InterestLedger: {
|
|
11
|
+
list: () => Promise<Map<string, "backward" | "forward">>;
|
|
12
|
+
forward: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
|
|
13
|
+
backward: (series_id: string, direction: "forward" | "backward") => Promise<void>;
|
|
14
|
+
patch: (series_id: string, direction: "forward" | "backward", signal: AbortSignal) => Promise<void>;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=interest-ledger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interest-ledger.d.ts","sourceRoot":"","sources":["../../src/series-collector/interest-ledger.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,2BAA2B,oDA8BvC,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,YAAY,MAAM,EAAE,aAAa,MAAM,WAChC,CAAC;AAErD,eAAO,MAAM,4BAA4B,GAAI,WAAW,MAAM;;;CAK7D,CAAC;AAcF,eAAO,MAAM,iCAAiC,GAC5C,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA4CpB,CAAC;AAEF,eAAO,MAAM,kCAAkC,GAC7C,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,kBA6ClC,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBAqCpB,CAAC;AAEF,eAAO,MAAM,cAAc;;yBA3Id,MAAM,aACN,SAAS,GAAG,UAAU,UACzB,WAAW;0BA+CR,MAAM,aACN,SAAS,GAAG,UAAU;uBAgDtB,MAAM,aACN,SAAS,GAAG,UAAU,UACzB,WAAW;CA4CpB,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InterestLedger = exports.handleIngestInterestLedgerPatch = exports.handleIngestInterestLedgerBackward = exports.handleIngestInterestLedgerForward = exports.decodeInterestLedgerSeriesId = exports.encodeInterestLedgerSeriesId = exports.listInterestLedgerSeriesIds = void 0;
|
|
4
|
+
const protocol_1 = require("@yuants/protocol");
|
|
5
|
+
const utils_1 = require("@yuants/utils");
|
|
6
|
+
const credential_1 = require("../credential");
|
|
7
|
+
const sql_helpers_1 = require("./sql-helpers");
|
|
8
|
+
const parseInterestLedgerServiceMetadataFromSchema = (schema) => {
|
|
9
|
+
//
|
|
10
|
+
return {
|
|
11
|
+
type: schema.properties.credential.properties.type.const,
|
|
12
|
+
direction: schema.properties.direction.const,
|
|
13
|
+
ledgerTypes: schema.properties.ledger_type.enum,
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
17
|
+
const listInterestLedgerSeriesIds = async () => {
|
|
18
|
+
// List All Credentials from VEX
|
|
19
|
+
const credentials = await terminal.client.requestForResponseData('VEX/ListExchangeCredential', {});
|
|
20
|
+
const series_ids = new Map();
|
|
21
|
+
for (const terminalInfo of terminal.terminalInfos) {
|
|
22
|
+
for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {
|
|
23
|
+
if (serviceInfo.method !== 'IngestInterestLedger')
|
|
24
|
+
continue;
|
|
25
|
+
try {
|
|
26
|
+
const meta = parseInterestLedgerServiceMetadataFromSchema(serviceInfo.schema);
|
|
27
|
+
for (const credential of credentials) {
|
|
28
|
+
if (!credential.credentialId)
|
|
29
|
+
continue;
|
|
30
|
+
if (credential.credential.type !== meta.type)
|
|
31
|
+
continue;
|
|
32
|
+
for (const ledgerType of meta.ledgerTypes) {
|
|
33
|
+
const series_id = (0, exports.encodeInterestLedgerSeriesId)(credential.credentialId, ledgerType);
|
|
34
|
+
series_ids.set(series_id, meta.direction);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return series_ids;
|
|
43
|
+
};
|
|
44
|
+
exports.listInterestLedgerSeriesIds = listInterestLedgerSeriesIds;
|
|
45
|
+
const encodeInterestLedgerSeriesId = (account_id, ledger_type) => (0, utils_1.encodePath)(...(0, utils_1.decodePath)(account_id), ledger_type);
|
|
46
|
+
exports.encodeInterestLedgerSeriesId = encodeInterestLedgerSeriesId;
|
|
47
|
+
const decodeInterestLedgerSeriesId = (series_id) => {
|
|
48
|
+
const parts = (0, utils_1.decodePath)(series_id);
|
|
49
|
+
const account_id = (0, utils_1.encodePath)(...parts.slice(0, -1));
|
|
50
|
+
const ledger_type = parts[parts.length - 1];
|
|
51
|
+
return { account_id, ledger_type };
|
|
52
|
+
};
|
|
53
|
+
exports.decodeInterestLedgerSeriesId = decodeInterestLedgerSeriesId;
|
|
54
|
+
const ingestCounter = terminal.metrics
|
|
55
|
+
.counter('series_collector_ingest_count', '')
|
|
56
|
+
.labels({ terminal_id: terminal.terminal_id, type: 'interest_ledger' });
|
|
57
|
+
const handleIngestInterestLedgerForward = async (series_id, direction, signal) => {
|
|
58
|
+
var _a, _b, _c, _d;
|
|
59
|
+
const { account_id, ledger_type } = (0, exports.decodeInterestLedgerSeriesId)(series_id);
|
|
60
|
+
const credential = await (0, credential_1.getCredentialByCredentialId)(account_id);
|
|
61
|
+
if (!credential)
|
|
62
|
+
throw (0, utils_1.newError)('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });
|
|
63
|
+
let req;
|
|
64
|
+
if (direction === 'forward') {
|
|
65
|
+
const endTime = await (0, sql_helpers_1.findForwardTaskLastEndTime)(terminal, series_id, 'account_interest_ledger');
|
|
66
|
+
const time = endTime ? new Date(endTime).getTime() : 0;
|
|
67
|
+
req = {
|
|
68
|
+
account_id,
|
|
69
|
+
direction,
|
|
70
|
+
time,
|
|
71
|
+
ledger_type,
|
|
72
|
+
credential,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
req = {
|
|
77
|
+
account_id,
|
|
78
|
+
direction,
|
|
79
|
+
time: Date.now(),
|
|
80
|
+
ledger_type,
|
|
81
|
+
credential,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const res = await terminal.client.requestForResponseData('IngestInterestLedger', req);
|
|
85
|
+
ingestCounter.labels({ task: 'forward' }).inc(res.wrote_count || 0);
|
|
86
|
+
console.info((0, utils_1.formatTime)(Date.now()), '[SeriesCollector][InterestLedger][Forward]', 'Result', `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${(0, utils_1.formatTime)((_b = (_a = res.range) === null || _a === void 0 ? void 0 : _a.start_time) !== null && _b !== void 0 ? _b : NaN)}, end_time=${(0, utils_1.formatTime)((_d = (_c = res.range) === null || _c === void 0 ? void 0 : _c.end_time) !== null && _d !== void 0 ? _d : NaN)}`);
|
|
87
|
+
};
|
|
88
|
+
exports.handleIngestInterestLedgerForward = handleIngestInterestLedgerForward;
|
|
89
|
+
const handleIngestInterestLedgerBackward = async (series_id, direction) => {
|
|
90
|
+
var _a, _b, _c, _d;
|
|
91
|
+
const { account_id, ledger_type } = (0, exports.decodeInterestLedgerSeriesId)(series_id);
|
|
92
|
+
const credential = await (0, credential_1.getCredentialByCredentialId)(account_id);
|
|
93
|
+
if (!credential)
|
|
94
|
+
throw (0, utils_1.newError)('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });
|
|
95
|
+
let req;
|
|
96
|
+
if (direction === 'backward') {
|
|
97
|
+
const startTime = await (0, sql_helpers_1.findBackwardTaskFirstStartTime)(terminal, series_id, 'account_interest_ledger');
|
|
98
|
+
const time = startTime ? new Date(startTime).getTime() : Date.now();
|
|
99
|
+
req = {
|
|
100
|
+
account_id,
|
|
101
|
+
direction,
|
|
102
|
+
time,
|
|
103
|
+
ledger_type,
|
|
104
|
+
credential,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// do backward using forward request with time = 0
|
|
109
|
+
req = {
|
|
110
|
+
account_id,
|
|
111
|
+
direction,
|
|
112
|
+
time: 0,
|
|
113
|
+
ledger_type,
|
|
114
|
+
credential,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const res = await terminal.client.requestForResponseData('IngestInterestLedger', req);
|
|
118
|
+
ingestCounter.labels({ task: 'backward' }).inc(res.wrote_count || 0);
|
|
119
|
+
console.info((0, utils_1.formatTime)(Date.now()), '[SeriesCollector][InterestLedger][Backward]', 'Result', `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${(0, utils_1.formatTime)((_b = (_a = res.range) === null || _a === void 0 ? void 0 : _a.start_time) !== null && _b !== void 0 ? _b : NaN)}, end_time=${(0, utils_1.formatTime)((_d = (_c = res.range) === null || _c === void 0 ? void 0 : _c.end_time) !== null && _d !== void 0 ? _d : NaN)}`);
|
|
120
|
+
};
|
|
121
|
+
exports.handleIngestInterestLedgerBackward = handleIngestInterestLedgerBackward;
|
|
122
|
+
const handleIngestInterestLedgerPatch = async (series_id, direction, signal) => {
|
|
123
|
+
var _a, _b, _c, _d;
|
|
124
|
+
const { account_id, ledger_type } = (0, exports.decodeInterestLedgerSeriesId)(series_id);
|
|
125
|
+
const credential = await (0, credential_1.getCredentialByCredentialId)(account_id);
|
|
126
|
+
if (!credential)
|
|
127
|
+
throw (0, utils_1.newError)('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });
|
|
128
|
+
const patch = await (0, sql_helpers_1.findPatchGap)(terminal, 'account_interest_ledger', series_id);
|
|
129
|
+
if (!patch)
|
|
130
|
+
return; // no gap
|
|
131
|
+
const time = direction === 'forward'
|
|
132
|
+
? new Date(patch.gap_start_time).getTime()
|
|
133
|
+
: new Date(patch.gap_end_time).getTime();
|
|
134
|
+
const req = {
|
|
135
|
+
account_id,
|
|
136
|
+
direction,
|
|
137
|
+
time,
|
|
138
|
+
ledger_type,
|
|
139
|
+
credential,
|
|
140
|
+
};
|
|
141
|
+
const res = await terminal.client.requestForResponseData('IngestInterestLedger', req);
|
|
142
|
+
ingestCounter.labels({ task: 'patch' }).inc(res.wrote_count || 0);
|
|
143
|
+
console.info((0, utils_1.formatTime)(Date.now()), '[SeriesCollector][InterestLedger][Patch]', 'Result', `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${(0, utils_1.formatTime)((_b = (_a = res.range) === null || _a === void 0 ? void 0 : _a.start_time) !== null && _b !== void 0 ? _b : NaN)}, end_time=${(0, utils_1.formatTime)((_d = (_c = res.range) === null || _c === void 0 ? void 0 : _c.end_time) !== null && _d !== void 0 ? _d : NaN)}`);
|
|
144
|
+
};
|
|
145
|
+
exports.handleIngestInterestLedgerPatch = handleIngestInterestLedgerPatch;
|
|
146
|
+
exports.InterestLedger = {
|
|
147
|
+
list: exports.listInterestLedgerSeriesIds,
|
|
148
|
+
forward: exports.handleIngestInterestLedgerForward,
|
|
149
|
+
backward: exports.handleIngestInterestLedgerBackward,
|
|
150
|
+
patch: exports.handleIngestInterestLedgerPatch,
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=interest-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interest-ledger.js","sourceRoot":"","sources":["../../src/series-collector/interest-ledger.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA6E;AAC7E,8CAA4D;AAE5D,+CAAyG;AAEzG,MAAM,4CAA4C,GAAG,CACnD,MAAW,EACiE,EAAE;IAC9E,EAAE;IACF,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK;QACxD,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,KAAK;QAC5C,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI;KAChD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAEjC,MAAM,2BAA2B,GAAG,KAAK,IAAI,EAAE;IACpD,gCAAgC;IAChC,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CAG9D,4BAA4B,EAAE,EAAE,CAAC,CAAC;IAEpC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE7D,KAAK,MAAM,YAAY,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QAClD,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,WAAW,CAAC,MAAM,KAAK,sBAAsB;gBAAE,SAAS;YAC5D,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,4CAA4C,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAE9E,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;oBACrC,IAAI,CAAC,UAAU,CAAC,YAAY;wBAAE,SAAS;oBACvC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;wBAAE,SAAS;oBAEvD,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC1C,MAAM,SAAS,GAAG,IAAA,oCAA4B,EAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;wBACpF,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AA9BW,QAAA,2BAA2B,+BA8BtC;AAEK,MAAM,4BAA4B,GAAG,CAAC,UAAkB,EAAE,WAAmB,EAAE,EAAE,CACtF,IAAA,kBAAU,EAAC,GAAG,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;AADxC,QAAA,4BAA4B,gCACY;AAE9C,MAAM,4BAA4B,GAAG,CAAC,SAAiB,EAAE,EAAE;IAChE,MAAM,KAAK,GAAG,IAAA,kBAAU,EAAC,SAAS,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,IAAA,kBAAU,EAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACrC,CAAC,CAAC;AALW,QAAA,4BAA4B,gCAKvC;AAUF,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC;AAEnE,MAAM,iCAAiC,GAAG,KAAK,EACpD,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAA,oCAA4B,EAAC,SAAS,CAAC,CAAC;IAE5E,MAAM,UAAU,GAAG,MAAM,IAAA,wCAA2B,EAAC,UAAU,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU;QAAE,MAAM,IAAA,gBAAQ,EAAC,2CAA2C,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE7F,IAAI,GAAiC,CAAC;IAEtC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAA,wCAA0B,EAAC,QAAQ,EAAE,SAAS,EAAE,yBAAyB,CAAC,CAAC;QACjG,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,GAAG,GAAG;YACJ,UAAU;YACV,SAAS;YACT,IAAI;YACJ,WAAW;YACX,UAAU;SACX,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,GAAG,GAAG;YACJ,UAAU;YACV,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;YAChB,WAAW;YACX,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,sBAAsB,EACtB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAEpE,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,4CAA4C,EAC5C,QAAQ,EACR,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA/CW,QAAA,iCAAiC,qCA+C5C;AAEK,MAAM,kCAAkC,GAAG,KAAK,EACrD,SAAiB,EACjB,SAAiC,EACjC,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAA,oCAA4B,EAAC,SAAS,CAAC,CAAC;IAE5E,MAAM,UAAU,GAAG,MAAM,IAAA,wCAA2B,EAAC,UAAU,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU;QAAE,MAAM,IAAA,gBAAQ,EAAC,2CAA2C,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE7F,IAAI,GAAiC,CAAC;IAEtC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,MAAM,IAAA,4CAA8B,EAAC,QAAQ,EAAE,SAAS,EAAE,yBAAyB,CAAC,CAAC;QACvG,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACpE,GAAG,GAAG;YACJ,UAAU;YACV,SAAS;YACT,IAAI;YACJ,WAAW;YACX,UAAU;SACX,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,kDAAkD;QAClD,GAAG,GAAG;YACJ,UAAU;YACV,SAAS;YACT,IAAI,EAAE,CAAC;YACP,WAAW;YACX,UAAU;SACX,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,sBAAsB,EACtB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAErE,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,6CAA6C,EAC7C,QAAQ,EACR,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA/CW,QAAA,kCAAkC,sCA+C7C;AAEK,MAAM,+BAA+B,GAAG,KAAK,EAClD,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAA,oCAA4B,EAAC,SAAS,CAAC,CAAC;IAE5E,MAAM,UAAU,GAAG,MAAM,IAAA,wCAA2B,EAAC,UAAU,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU;QAAE,MAAM,IAAA,gBAAQ,EAAC,2CAA2C,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE7F,MAAM,KAAK,GAAG,MAAM,IAAA,0BAAY,EAAC,QAAQ,EAAE,yBAAyB,EAAE,SAAS,CAAC,CAAC;IAEjF,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,SAAS;IAC7B,MAAM,IAAI,GACR,SAAS,KAAK,SAAS;QACrB,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE;QAC1C,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAiC;QACxC,UAAU;QACV,SAAS;QACT,IAAI;QACJ,WAAW;QACX,UAAU;KACX,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,sBAAsB,EACtB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAElE,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,0CAA0C,EAC1C,QAAQ,EACR,aAAa,SAAS,oBAAoB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACjF,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AAxCW,QAAA,+BAA+B,mCAwC1C;AAEW,QAAA,cAAc,GAAG;IAC5B,IAAI,EAAE,mCAA2B;IACjC,OAAO,EAAE,yCAAiC;IAC1C,QAAQ,EAAE,0CAAkC;IAC5C,KAAK,EAAE,uCAA+B;CACvC,CAAC","sourcesContent":["import { ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { decodePath, encodePath, formatTime, newError } from '@yuants/utils';\nimport { getCredentialByCredentialId } from '../credential';\nimport { IExchangeCredential } from '../types';\nimport { findBackwardTaskFirstStartTime, findForwardTaskLastEndTime, findPatchGap } from './sql-helpers';\n\nconst parseInterestLedgerServiceMetadataFromSchema = (\n schema: any,\n): { type: string; direction: 'backward' | 'forward'; ledgerTypes: string[] } => {\n //\n return {\n type: schema.properties.credential.properties.type.const,\n direction: schema.properties.direction.const,\n ledgerTypes: schema.properties.ledger_type.enum,\n };\n};\n\nconst terminal = Terminal.fromNodeEnv();\n\nexport const listInterestLedgerSeriesIds = async () => {\n // List All Credentials from VEX\n const credentials = await terminal.client.requestForResponseData<\n {},\n Array<{ sign: string; credential: IExchangeCredential; credentialId?: string }>\n >('VEX/ListExchangeCredential', {});\n\n const series_ids = new Map<string, 'forward' | 'backward'>();\n\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestInterestLedger') continue;\n try {\n const meta = parseInterestLedgerServiceMetadataFromSchema(serviceInfo.schema);\n\n for (const credential of credentials) {\n if (!credential.credentialId) continue;\n if (credential.credential.type !== meta.type) continue;\n\n for (const ledgerType of meta.ledgerTypes) {\n const series_id = encodeInterestLedgerSeriesId(credential.credentialId, ledgerType);\n series_ids.set(series_id, meta.direction);\n }\n }\n } finally {\n }\n }\n }\n\n return series_ids;\n};\n\nexport const encodeInterestLedgerSeriesId = (account_id: string, ledger_type: string) =>\n encodePath(...decodePath(account_id), ledger_type);\n\nexport const decodeInterestLedgerSeriesId = (series_id: string) => {\n const parts = decodePath(series_id);\n const account_id = encodePath(...parts.slice(0, -1));\n const ledger_type = parts[parts.length - 1];\n return { account_id, ledger_type };\n};\n\ninterface IIngestInterestLedgerRequest {\n account_id: string;\n direction: 'forward' | 'backward';\n time: number;\n ledger_type: string;\n credential: IExchangeCredential;\n}\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_ledger' });\n\nexport const handleIngestInterestLedgerForward = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const { account_id, ledger_type } = decodeInterestLedgerSeriesId(series_id);\n\n const credential = await getCredentialByCredentialId(account_id);\n if (!credential) throw newError('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });\n\n let req: IIngestInterestLedgerRequest;\n\n if (direction === 'forward') {\n const endTime = await findForwardTaskLastEndTime(terminal, series_id, 'account_interest_ledger');\n const time = endTime ? new Date(endTime).getTime() : 0;\n req = {\n account_id,\n direction,\n time,\n ledger_type,\n credential,\n };\n } else {\n req = {\n account_id,\n direction,\n time: Date.now(),\n ledger_type,\n credential,\n };\n }\n\n const res = await terminal.client.requestForResponseData<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestInterestLedger',\n req,\n );\n\n ingestCounter.labels({ task: 'forward' }).inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestLedger][Forward]',\n 'Result',\n `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n\nexport const handleIngestInterestLedgerBackward = async (\n series_id: string,\n direction: 'forward' | 'backward',\n) => {\n const { account_id, ledger_type } = decodeInterestLedgerSeriesId(series_id);\n\n const credential = await getCredentialByCredentialId(account_id);\n if (!credential) throw newError('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });\n\n let req: IIngestInterestLedgerRequest;\n\n if (direction === 'backward') {\n const startTime = await findBackwardTaskFirstStartTime(terminal, series_id, 'account_interest_ledger');\n const time = startTime ? new Date(startTime).getTime() : Date.now();\n req = {\n account_id,\n direction,\n time,\n ledger_type,\n credential,\n };\n } else {\n // do backward using forward request with time = 0\n req = {\n account_id,\n direction,\n time: 0,\n ledger_type,\n credential,\n };\n }\n\n const res = await terminal.client.requestForResponseData<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestInterestLedger',\n req,\n );\n\n ingestCounter.labels({ task: 'backward' }).inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestLedger][Backward]',\n 'Result',\n `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n\nexport const handleIngestInterestLedgerPatch = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const { account_id, ledger_type } = decodeInterestLedgerSeriesId(series_id);\n\n const credential = await getCredentialByCredentialId(account_id);\n if (!credential) throw newError('CREDENTIAL_NOT_FOUND_WHEN_HANDLING_INGEST', { account_id });\n\n const patch = await findPatchGap(terminal, 'account_interest_ledger', series_id);\n\n if (!patch) return; // no gap\n const time =\n direction === 'forward'\n ? new Date(patch.gap_start_time).getTime()\n : new Date(patch.gap_end_time).getTime();\n const req: IIngestInterestLedgerRequest = {\n account_id,\n direction,\n time,\n ledger_type,\n credential,\n };\n\n const res = await terminal.client.requestForResponseData<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestInterestLedger',\n req,\n );\n\n ingestCounter.labels({ task: 'patch' }).inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestLedger][Patch]',\n 'Result',\n `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n\nexport const InterestLedger = {\n list: listInterestLedgerSeriesIds,\n forward: handleIngestInterestLedgerForward,\n backward: handleIngestInterestLedgerBackward,\n patch: handleIngestInterestLedgerPatch,\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,uBAAuB,GAClC,YAAY,MAAM,EAClB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,
|
|
1
|
+
{"version":3,"file":"patch-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,uBAAuB,GAClC,YAAY,MAAM,EAClB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA2DpB,CAAC"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.handleInterestRatePatch = void 0;
|
|
4
4
|
const protocol_1 = require("@yuants/protocol");
|
|
5
|
-
const sql_1 = require("@yuants/sql");
|
|
6
5
|
const utils_1 = require("@yuants/utils");
|
|
6
|
+
const sql_helpers_1 = require("./sql-helpers");
|
|
7
7
|
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
8
8
|
const ingestCounter = terminal.metrics
|
|
9
9
|
.counter('series_collector_ingest_count', '')
|
|
@@ -11,28 +11,7 @@ const ingestCounter = terminal.metrics
|
|
|
11
11
|
// Patch 任务:查找数据缺口并进行补齐
|
|
12
12
|
const handleInterestRatePatch = async (product_id, direction, signal) => {
|
|
13
13
|
var _a, _b, _c, _d;
|
|
14
|
-
const
|
|
15
|
-
WITH reversed_ranges AS (
|
|
16
|
-
SELECT
|
|
17
|
-
start_time,
|
|
18
|
-
end_time,
|
|
19
|
-
LEAD(end_time) OVER (
|
|
20
|
-
PARTITION BY table_name, series_id
|
|
21
|
-
ORDER BY start_time DESC
|
|
22
|
-
) AS next_end_time -- 注意:倒序时 LEAD 是前一个区间
|
|
23
|
-
FROM series_data_range
|
|
24
|
-
WHERE table_name = 'interest_rate'
|
|
25
|
-
AND series_id = ${(0, sql_1.escapeSQL)(product_id)}
|
|
26
|
-
)
|
|
27
|
-
SELECT
|
|
28
|
-
next_end_time AS gap_start_time, -- 前一个区间的结束时间
|
|
29
|
-
start_time AS gap_end_time -- 当前区间的开始时间
|
|
30
|
-
FROM reversed_ranges
|
|
31
|
-
WHERE next_end_time IS NOT NULL
|
|
32
|
-
AND start_time > next_end_time -- 有空缺
|
|
33
|
-
ORDER BY start_time DESC -- 从最新开始
|
|
34
|
-
LIMIT 1;
|
|
35
|
-
`);
|
|
14
|
+
const record = await (0, sql_helpers_1.findPatchGap)(terminal, 'interest_rate', product_id);
|
|
36
15
|
// no gap
|
|
37
16
|
if (!record)
|
|
38
17
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"patch-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/patch-interest-rate.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAA6C;AAE7C,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEzF,uBAAuB;AAChB,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAY,EAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;IAEzE,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,SAAS,EACT,UAAU,UAAU,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,CACvF,CAAC;IAEF,IAAI,GAA+B,CAAC;IAEpC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,oBAAoB,EACpB,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,wCAAwC,EACxC,UAAU,EACV,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AA9DW,QAAA,uBAAuB,2BA8DlC","sourcesContent":["import { IIngestInterestRateRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { formatTime } from '@yuants/utils';\nimport { findPatchGap } from './sql-helpers';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate', task: 'forward' });\n\n// Patch 任务:查找数据缺口并进行补齐\nexport const handleInterestRatePatch = async (\n product_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const record = await findPatchGap(terminal, 'interest_rate', product_id);\n\n // no gap\n if (!record) return;\n\n const gapStartTime = new Date(record.gap_start_time).getTime();\n const gapEndTime = new Date(record.gap_end_time).getTime();\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n 'FindGap',\n `series=${product_id}, from=${formatTime(gapStartTime)}, to=${formatTime(gapEndTime)}`,\n );\n\n let req: IIngestInterestRateRequest;\n\n if (direction === 'forward') {\n // forward patch\n req = {\n product_id: product_id,\n direction: 'forward' as const,\n time: gapStartTime,\n };\n } else {\n // backward patch\n req = {\n product_id: product_id,\n direction: 'backward' as const,\n time: gapEndTime,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n product_id,\n 'PatchRequest',\n `direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][InterestRate][Patch]',\n product_id,\n 'PatchBackwardResult',\n `ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,
|
|
1
|
+
{"version":3,"file":"patch-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,qBAAqB,GAChC,WAAW,MAAM,EACjB,WAAW,SAAS,GAAG,UAAU,EACjC,QAAQ,WAAW,kBA+DpB,CAAC"}
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.handleIngestOHLCPatch = void 0;
|
|
4
4
|
const data_ohlc_1 = require("@yuants/data-ohlc");
|
|
5
5
|
const protocol_1 = require("@yuants/protocol");
|
|
6
|
-
const sql_1 = require("@yuants/sql");
|
|
7
6
|
const utils_1 = require("@yuants/utils");
|
|
7
|
+
const sql_helpers_1 = require("./sql-helpers");
|
|
8
8
|
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
9
9
|
const ingestCounter = terminal.metrics
|
|
10
10
|
.counter('series_collector_ingest_count', '')
|
|
@@ -12,28 +12,7 @@ const ingestCounter = terminal.metrics
|
|
|
12
12
|
// Patch 任务:查找数据缺口并进行补齐
|
|
13
13
|
const handleIngestOHLCPatch = async (series_id, direction, signal) => {
|
|
14
14
|
var _a, _b, _c, _d;
|
|
15
|
-
const
|
|
16
|
-
WITH reversed_ranges AS (
|
|
17
|
-
SELECT
|
|
18
|
-
start_time,
|
|
19
|
-
end_time,
|
|
20
|
-
LEAD(end_time) OVER (
|
|
21
|
-
PARTITION BY table_name, series_id
|
|
22
|
-
ORDER BY start_time DESC
|
|
23
|
-
) AS next_end_time -- 注意:倒序时 LEAD 是前一个区间
|
|
24
|
-
FROM series_data_range
|
|
25
|
-
WHERE table_name = 'ohlc_v2'
|
|
26
|
-
AND series_id = ${(0, sql_1.escapeSQL)(series_id)}
|
|
27
|
-
)
|
|
28
|
-
SELECT
|
|
29
|
-
next_end_time AS gap_start_time, -- 前一个区间的结束时间
|
|
30
|
-
start_time AS gap_end_time -- 当前区间的开始时间
|
|
31
|
-
FROM reversed_ranges
|
|
32
|
-
WHERE next_end_time IS NOT NULL
|
|
33
|
-
AND start_time > next_end_time -- 有空缺
|
|
34
|
-
ORDER BY start_time DESC -- 从最新开始
|
|
35
|
-
LIMIT 1;
|
|
36
|
-
`);
|
|
15
|
+
const record = await (0, sql_helpers_1.findPatchGap)(terminal, 'ohlc_v2', series_id);
|
|
37
16
|
// no gap
|
|
38
17
|
if (!record)
|
|
39
18
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AAEvD,+CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"patch-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/patch-ohlc.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AAEvD,+CAA4C;AAC5C,yCAA2C;AAC3C,+CAA6C;AAE7C,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO;KACnC,OAAO,CAAC,+BAA+B,EAAE,EAAE,CAAC;KAC5C,MAAM,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAEhF,uBAAuB;AAChB,MAAM,qBAAqB,GAAG,KAAK,EACxC,SAAiB,EACjB,SAAiC,EACjC,MAAmB,EACnB,EAAE;;IACF,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAY,EAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAElE,SAAS;IACT,IAAI,CAAC,MAAM;QAAE,OAAO;IAEpB,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC;IAE3D,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,UAAU,SAAS,UAAU,IAAA,kBAAU,EAAC,YAAY,CAAC,QAAQ,IAAA,kBAAU,EAAC,UAAU,CAAC,EAAE,CACtF,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAA,8BAAkB,EAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,GAAuB,CAAC;IAE5B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,gBAAgB;QAChB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,SAAkB;YAC7B,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,iBAAiB;QACjB,GAAG,GAAG;YACJ,UAAU,EAAE,UAAU;YACtB,QAAQ;YACR,SAAS,EAAE,UAAmB;YAC9B,IAAI,EAAE,UAAU;SACjB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,cAAc,EACd,aAAa,GAAG,CAAC,SAAS,UAAU,IAAA,kBAAU,EAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAC3D,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,sBAAsB,CACtD,YAAY,EACZ,GAAG,CACJ,CAAC;IAEF,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAExC,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,gCAAgC,EAChC,SAAS,EACT,qBAAqB,EACrB,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,IAAA,kBAAU,EACzD,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,UAAU,mCAAI,GAAG,CAC7B,cAAc,IAAA,kBAAU,EAAC,MAAA,MAAA,GAAG,CAAC,KAAK,0CAAE,QAAQ,mCAAI,GAAG,CAAC,EAAE,CACxD,CAAC;AACJ,CAAC,CAAC;AAlEW,QAAA,qBAAqB,yBAkEhC","sourcesContent":["import { decodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport { IIngestOHLCRequest, ISeriesIngestResult } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { formatTime } from '@yuants/utils';\nimport { findPatchGap } from './sql-helpers';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst ingestCounter = terminal.metrics\n .counter('series_collector_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc', task: 'forward' });\n\n// Patch 任务:查找数据缺口并进行补齐\nexport const handleIngestOHLCPatch = async (\n series_id: string,\n direction: 'forward' | 'backward',\n signal: AbortSignal,\n) => {\n const record = await findPatchGap(terminal, 'ohlc_v2', series_id);\n\n // no gap\n if (!record) return;\n\n const gapStartTime = new Date(record.gap_start_time).getTime();\n const gapEndTime = new Date(record.gap_end_time).getTime();\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n 'FindGap',\n `series=${series_id}, from=${formatTime(gapStartTime)}, to=${formatTime(gapEndTime)}`,\n );\n\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n\n let req: IIngestOHLCRequest;\n\n if (direction === 'forward') {\n // forward patch\n req = {\n product_id: product_id,\n duration,\n direction: 'forward' as const,\n time: gapStartTime,\n };\n } else {\n // backward patch\n req = {\n product_id: product_id,\n duration,\n direction: 'backward' as const,\n time: gapEndTime,\n };\n }\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n series_id,\n 'PatchRequest',\n `direction=${req.direction}, time=${formatTime(req.time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n ingestCounter.inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n '[SeriesCollector][OHLC][Patch]',\n series_id,\n 'PatchBackwardResult',\n `ingested_count=${res.wrote_count}, start_time=${formatTime(\n res.range?.start_time ?? NaN,\n )}, end_time=${formatTime(res.range?.end_time ?? NaN)}`,\n );\n};\n"]}
|
|
@@ -6,6 +6,7 @@ const backwards_ohlc_1 = require("./backwards-ohlc");
|
|
|
6
6
|
const discovery_1 = require("./discovery");
|
|
7
7
|
const forwards_interest_rate_1 = require("./forwards-interest-rate");
|
|
8
8
|
const forwards_ohlc_1 = require("./forwards-ohlc");
|
|
9
|
+
const interest_ledger_1 = require("./interest-ledger");
|
|
9
10
|
const patch_interest_rate_1 = require("./patch-interest-rate");
|
|
10
11
|
const patch_ohlc_1 = require("./patch-ohlc");
|
|
11
12
|
const api = {
|
|
@@ -21,11 +22,12 @@ const api = {
|
|
|
21
22
|
backward: backwards_interest_rate_1.handleIngestInterestRateBackward,
|
|
22
23
|
patch: patch_interest_rate_1.handleInterestRatePatch,
|
|
23
24
|
},
|
|
25
|
+
InterestLedger: interest_ledger_1.InterestLedger,
|
|
24
26
|
};
|
|
25
27
|
(async () => {
|
|
26
28
|
const abortController = new AbortController();
|
|
27
29
|
const signal = abortController.signal;
|
|
28
|
-
for (const type of ['OHLC', 'InterestRate']) {
|
|
30
|
+
for (const type of ['OHLC', 'InterestRate', 'InterestLedger']) {
|
|
29
31
|
const list = api[type].list;
|
|
30
32
|
for (const task of ['forward', 'backward', 'patch']) {
|
|
31
33
|
const handler = api[type][task];
|
|
@@ -34,17 +36,7 @@ const api = {
|
|
|
34
36
|
await (0, utils_1.tokenBucket)(`${type}:${task}`).acquire(1, signal);
|
|
35
37
|
try {
|
|
36
38
|
const tasks = await list();
|
|
37
|
-
|
|
38
|
-
const groups = new Map();
|
|
39
|
-
for (const item of tasks) {
|
|
40
|
-
const [datasource_id] = (0, utils_1.decodePath)(item[0]);
|
|
41
|
-
let items = groups.get(datasource_id);
|
|
42
|
-
if (!items) {
|
|
43
|
-
items = [];
|
|
44
|
-
groups.set(datasource_id, items);
|
|
45
|
-
}
|
|
46
|
-
items.push(item);
|
|
47
|
-
}
|
|
39
|
+
const groups = Map.groupBy(tasks, (item) => (0, utils_1.decodePath)(item[0])[0]);
|
|
48
40
|
await Promise.all(Array.from(groups.entries()).map(async ([datasource_id, tasks]) => {
|
|
49
41
|
for (const [series_id, direction] of tasks) {
|
|
50
42
|
await (0, utils_1.tokenBucket)(`${type}:${task}:${datasource_id}`).acquire(1, signal);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/series-collector/setup.ts"],"names":[],"mappings":";;AAAA,yCAAoE;AACpE,uEAA6E;AAC7E,qDAA4D;AAC5D,2CAA2E;AAC3E,qEAA2E;AAC3E,mDAA0D;AAC1D,+DAAgE;AAChE,6CAAqD;AAErD,MAAM,GAAG,GAAG;IACV,IAAI,EAAE;QACJ,IAAI,EAAE,6BAAiB;QACvB,OAAO,EAAE,uCAAuB;QAChC,QAAQ,EAAE,yCAAwB;QAClC,KAAK,EAAE,kCAAqB;KAC7B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qCAAyB;QAC/B,OAAO,EAAE,wDAA+B;QACxC,QAAQ,EAAE,0DAAgC;QAC1C,KAAK,EAAE,6CAAuB;KAC/B;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/series-collector/setup.ts"],"names":[],"mappings":";;AAAA,yCAAoE;AACpE,uEAA6E;AAC7E,qDAA4D;AAC5D,2CAA2E;AAC3E,qEAA2E;AAC3E,mDAA0D;AAC1D,uDAAmD;AACnD,+DAAgE;AAChE,6CAAqD;AAErD,MAAM,GAAG,GAAG;IACV,IAAI,EAAE;QACJ,IAAI,EAAE,6BAAiB;QACvB,OAAO,EAAE,uCAAuB;QAChC,QAAQ,EAAE,yCAAwB;QAClC,KAAK,EAAE,kCAAqB;KAC7B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qCAAyB;QAC/B,OAAO,EAAE,wDAA+B;QACxC,QAAQ,EAAE,0DAAgC;QAC1C,KAAK,EAAE,6CAAuB;KAC/B;IACD,cAAc,EAAd,gCAAc;CACf,CAAC;AAEF,CAAC,KAAK,IAAI,EAAE;IACV,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAU,EAAE,CAAC;QACvE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAU,EAAE,CAAC;YAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC,KAAK,IAAI,EAAE;gBACV,OAAO,IAAI,EAAE,CAAC;oBACZ,MAAM,IAAA,mBAAW,EAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;oBACxD,IAAI,CAAC;wBACH,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAC;wBAE3B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAEpE,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE;4BAChE,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,KAAK,EAAE,CAAC;gCAC3C,MAAM,IAAA,mBAAW,EAAC,GAAG,IAAI,IAAI,IAAI,IAAI,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;gCACzE,MAAM,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oCACxD,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,qBAAqB,IAAI,KAAK,IAAI,GAAG,EACrC,SAAS,EACT,OAAO,EACP,GAAG,CACJ,CAAC;gCACJ,CAAC,CAAC,CAAC;4BACL,CAAC;wBACH,CAAC,CAAC,CACH,CAAC;oBACJ,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;gBAChB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;IACH,CAAC;AACH,CAAC,CAAC,EAAE,CAAC","sourcesContent":["import { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { handleIngestInterestRateBackward } from './backwards-interest-rate';\nimport { handleIngestOHLCBackward } from './backwards-ohlc';\nimport { listInterestRateSeriesIds, listOHLCSeriesIds } from './discovery';\nimport { handleIngestInterestRateForward } from './forwards-interest-rate';\nimport { handleIngestOHLCForward } from './forwards-ohlc';\nimport { InterestLedger } from './interest-ledger';\nimport { handleInterestRatePatch } from './patch-interest-rate';\nimport { handleIngestOHLCPatch } from './patch-ohlc';\n\nconst api = {\n OHLC: {\n list: listOHLCSeriesIds,\n forward: handleIngestOHLCForward,\n backward: handleIngestOHLCBackward,\n patch: handleIngestOHLCPatch,\n },\n InterestRate: {\n list: listInterestRateSeriesIds,\n forward: handleIngestInterestRateForward,\n backward: handleIngestInterestRateBackward,\n patch: handleInterestRatePatch,\n },\n InterestLedger,\n};\n\n(async () => {\n const abortController = new AbortController();\n const signal = abortController.signal;\n for (const type of ['OHLC', 'InterestRate', 'InterestLedger'] as const) {\n const list = api[type].list;\n for (const task of ['forward', 'backward', 'patch'] as const) {\n const handler = api[type][task];\n (async () => {\n while (true) {\n await tokenBucket(`${type}:${task}`).acquire(1, signal);\n try {\n const tasks = await list();\n\n const groups = Map.groupBy(tasks, (item) => decodePath(item[0])[0]);\n\n await Promise.all(\n Array.from(groups.entries()).map(async ([datasource_id, tasks]) => {\n for (const [series_id, direction] of tasks) {\n await tokenBucket(`${type}:${task}:${datasource_id}`).acquire(1, signal);\n await handler(series_id, direction, signal).catch((err) => {\n console.info(\n formatTime(Date.now()),\n `[SeriesCollector][${type}][${task}]`,\n series_id,\n 'Error',\n err,\n );\n });\n }\n }),\n );\n } catch (e) {}\n }\n })();\n }\n }\n})();\n"]}
|
|
@@ -8,4 +8,10 @@ import { Terminal } from '@yuants/protocol';
|
|
|
8
8
|
export declare const findInterestRateEndTimeForward: (terminal: Terminal, product_id: string) => Promise<string>;
|
|
9
9
|
export declare const findInterestRateStartTimeBackward: (terminal: Terminal, product_id: string) => Promise<string>;
|
|
10
10
|
export declare const findOHLCEndTimeForward: (terminal: Terminal, series_id: string) => Promise<string>;
|
|
11
|
+
export declare const findForwardTaskLastEndTime: (terminal: Terminal, series_id: string, table_name: string) => Promise<string>;
|
|
12
|
+
export declare const findBackwardTaskFirstStartTime: (terminal: Terminal, series_id: string, table_name: string) => Promise<string>;
|
|
13
|
+
export declare const findPatchGap: (terminal: Terminal, table_name: string, series_id: string) => Promise<{
|
|
14
|
+
gap_start_time: string;
|
|
15
|
+
gap_end_time: string;
|
|
16
|
+
} | undefined>;
|
|
11
17
|
//# sourceMappingURL=sql-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-helpers.d.ts","sourceRoot":"","sources":["../../src/series-collector/sql-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUxC,CAAC;AAE9C,eAAO,MAAM,iCAAiC,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUzC,CAAC;AAEhD,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM,oBAU/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"sql-helpers.d.ts","sourceRoot":"","sources":["../../src/series-collector/sql-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUxC,CAAC;AAE9C,eAAO,MAAM,iCAAiC,GAAI,UAAU,QAAQ,EAAE,YAAY,MAAM,oBAUzC,CAAC;AAEhD,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM,oBAU/B,CAAC;AAE9C,eAAO,MAAM,0BAA0B,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM,EAAE,YAAY,MAAM,oBAUvD,CAAC;AAE9C,eAAO,MAAM,8BAA8B,GAAI,UAAU,QAAQ,EAAE,WAAW,MAAM,EAAE,YAAY,MAAM,oBAUzD,CAAC;AAEhD,eAAO,MAAM,YAAY,GACvB,UAAU,QAAQ,EAClB,YAAY,MAAM,EAClB,WAAW,MAAM,KAChB,OAAO,CACN;IACE,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB,GACD,SAAS,CA6BZ,CAAC"}
|