@yuants/app-virtual-exchange 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,4 +3,6 @@ import './general';
3
3
  import './legacy-services';
4
4
  import './product-collector';
5
5
  import './quote/service';
6
+ import './series-collector';
7
+ import './series-data';
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC;AACnB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iBAAiB,CAAC","sourcesContent":["import './credential';\nimport './general';\nimport './legacy-services';\nimport './product-collector';\nimport './quote/service';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC;AACnB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iBAAiB,CAAC;AACzB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,eAAe,CAAC","sourcesContent":["import './credential';\nimport './general';\nimport './legacy-services';\nimport './product-collector';\nimport './quote/service';\nimport './series-collector';\nimport './series-data';\n"]}
@@ -0,0 +1,73 @@
1
+ // 解决 Backwards 拉取历史数据的调度器
2
+ // 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。
3
+ // 然后对每个序列,向对应的 IngestInterestRate Service 发送拉取请求,补齐历史数据。
4
+ // 使用 Token Bucket 控制每个数据源的请求速率,避免过载。
5
+ import { parseInterestRateServiceMetadataFromSchema, } from '@yuants/exchange';
6
+ import { Terminal } from '@yuants/protocol';
7
+ import { escapeSQL, requestSQL } from '@yuants/sql';
8
+ import { decodePath, formatTime, tokenBucket } from '@yuants/utils';
9
+ import { defer, repeat, retry } from 'rxjs';
10
+ const terminal = Terminal.fromNodeEnv();
11
+ const listBackwardSeriesIds = async () => {
12
+ const product_ids = await requestSQL(terminal, `select product_id from product`);
13
+ console.time('[SeriesCollector][InterestRate][Backwards] calc');
14
+ const series_ids = new Set();
15
+ for (const terminalInfo of terminal.terminalInfos) {
16
+ for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {
17
+ if (serviceInfo.method !== 'IngestInterestRate')
18
+ continue;
19
+ try {
20
+ const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);
21
+ if (meta.direction !== 'backward')
22
+ continue;
23
+ for (const { product_id } of product_ids) {
24
+ if (!product_id.startsWith(meta.product_id_prefix))
25
+ continue;
26
+ series_ids.add(product_id);
27
+ }
28
+ }
29
+ finally {
30
+ }
31
+ }
32
+ }
33
+ console.timeEnd('[SeriesCollector][InterestRate][Backwards] calc');
34
+ return series_ids;
35
+ };
36
+ defer(async () => {
37
+ const time = Date.now();
38
+ const series_ids = await listBackwardSeriesIds();
39
+ console.log(`[SeriesCollector][InterestRate][Backwards] Found ${series_ids.size} series to collect backwards data for. (${formatTime(Date.now() - time)})`);
40
+ await Promise.all([...series_ids].map(async (product_id) => {
41
+ var _a, _b, _c, _d;
42
+ try {
43
+ const [datasource_id] = decodePath(product_id);
44
+ // 控制速率:每个数据源每秒钟只能请求一次
45
+ await tokenBucket(`interest_rate_backwards:${datasource_id}`, {
46
+ refillInterval: 1000,
47
+ capacity: 1,
48
+ }).acquire();
49
+ {
50
+ const [record] = await requestSQL(terminal, `select start_time from series_data_range where series_id = ${escapeSQL(product_id)} and table_name = 'interest_rate' order by start_time limit 1`);
51
+ const start_time = record ? new Date(record.start_time).getTime() : Date.now();
52
+ const req = {
53
+ product_id: product_id,
54
+ direction: 'backward',
55
+ time: start_time,
56
+ };
57
+ console.info(formatTime(Date.now()), 'DispatchIngestInterestRateRequest', `product_id=${product_id}, time=${formatTime(start_time)}`);
58
+ const res = await terminal.client.requestForResponseData('IngestInterestRate', req);
59
+ terminal.metrics
60
+ .counter('series_collector_backwards_ingest_count', '')
61
+ .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate' })
62
+ .inc(res.wrote_count || 0);
63
+ console.info(formatTime(Date.now()), 'DispatchIngestInterestRateResult', `series_id=${product_id}, ingested_count=${res.wrote_count}, start_time=${formatTime((_b = (_a = res.range) === null || _a === void 0 ? void 0 : _a.start_time) !== null && _b !== void 0 ? _b : NaN)}, end_time=${formatTime((_d = (_c = res.range) === null || _c === void 0 ? void 0 : _c.end_time) !== null && _d !== void 0 ? _d : NaN)}`);
64
+ }
65
+ }
66
+ catch (e) {
67
+ console.info(formatTime(Date.now()), 'DispatchIngestInterestRateError', `series_id=${product_id}`, e);
68
+ }
69
+ }));
70
+ })
71
+ .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))
72
+ .subscribe();
73
+ //# sourceMappingURL=backwards-interest-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":"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","sourcesContent":["// 解决 Backwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestInterestRate Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport {\n IIngestInterestRateRequest,\n ISeriesIngestResult,\n parseInterestRateServiceMetadataFromSchema,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { defer, repeat, retry } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst listBackwardSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(terminal, `select product_id from product`);\n\n console.time('[SeriesCollector][InterestRate][Backwards] calc');\n\n const series_ids = new Set<string>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestInterestRate') continue;\n try {\n const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);\n if (meta.direction !== 'backward') continue;\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n series_ids.add(product_id);\n }\n } finally {\n }\n }\n }\n\n console.timeEnd('[SeriesCollector][InterestRate][Backwards] calc');\n\n return series_ids;\n};\n\ndefer(async () => {\n const time = Date.now();\n const series_ids = await listBackwardSeriesIds();\n console.log(\n `[SeriesCollector][InterestRate][Backwards] Found ${\n series_ids.size\n } series to collect backwards data for. (${formatTime(Date.now() - time)})`,\n );\n\n await Promise.all(\n [...series_ids].map(async (product_id) => {\n try {\n const [datasource_id] = decodePath(product_id);\n // 控制速率:每个数据源每秒钟只能请求一次\n await tokenBucket(`interest_rate_backwards:${datasource_id}`, {\n refillInterval: 1000,\n capacity: 1,\n }).acquire();\n {\n const [record] = await requestSQL<\n {\n start_time: string;\n }[]\n >(\n terminal,\n `select start_time from series_data_range where series_id = ${escapeSQL(\n product_id,\n )} and table_name = 'interest_rate' order by start_time limit 1`,\n );\n const start_time = record ? new Date(record.start_time).getTime() : Date.now();\n\n const req: IIngestInterestRateRequest = {\n product_id: product_id,\n direction: 'backward',\n time: start_time,\n };\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestInterestRateRequest',\n `product_id=${product_id}, time=${formatTime(start_time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<\n IIngestInterestRateRequest,\n ISeriesIngestResult\n >('IngestInterestRate', req);\n\n terminal.metrics\n .counter('series_collector_backwards_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate' })\n .inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestInterestRateResult',\n `series_id=${product_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 } catch (e) {\n console.info(formatTime(Date.now()), 'DispatchIngestInterestRateError', `series_id=${product_id}`, e);\n }\n }),\n );\n})\n .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))\n .subscribe();\n"]}
@@ -0,0 +1,79 @@
1
+ // 解决 Backwards 拉取历史数据的调度器
2
+ // 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。
3
+ // 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。
4
+ // 使用 Token Bucket 控制每个数据源的请求速率,避免过载。
5
+ import { decodeOHLCSeriesId, encodeOHLCSeriesId } from '@yuants/data-ohlc';
6
+ import { parseOHLCServiceMetadataFromSchema, } from '@yuants/exchange';
7
+ import { Terminal } from '@yuants/protocol';
8
+ import { escapeSQL, requestSQL } from '@yuants/sql';
9
+ import { decodePath, formatTime, tokenBucket } from '@yuants/utils';
10
+ import { defer, repeat, retry } from 'rxjs';
11
+ const terminal = Terminal.fromNodeEnv();
12
+ const listBackwardSeriesIds = async () => {
13
+ const product_ids = await requestSQL(terminal, `select product_id from product`);
14
+ console.time('[SeriesCollector][Backwards] calc');
15
+ const series_ids = new Set();
16
+ for (const terminalInfo of terminal.terminalInfos) {
17
+ for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {
18
+ if (serviceInfo.method !== 'IngestOHLC')
19
+ continue;
20
+ try {
21
+ const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);
22
+ if (meta.direction !== 'backward')
23
+ continue;
24
+ for (const { product_id } of product_ids) {
25
+ if (!product_id.startsWith(meta.product_id_prefix))
26
+ continue;
27
+ for (const duration of meta.duration_list) {
28
+ const series_id = encodeOHLCSeriesId(product_id, duration);
29
+ series_ids.add(series_id);
30
+ }
31
+ }
32
+ }
33
+ finally {
34
+ }
35
+ }
36
+ }
37
+ console.timeEnd('[SeriesCollector][Backwards] calc');
38
+ return series_ids;
39
+ };
40
+ defer(async () => {
41
+ const time = Date.now();
42
+ const series_ids = await listBackwardSeriesIds();
43
+ console.log(`[SeriesCollector][Backwards] Found ${series_ids.size} series to collect backwards data for. (${formatTime(Date.now() - time)})`);
44
+ await Promise.all([...series_ids].map(async (series_id) => {
45
+ var _a, _b, _c, _d;
46
+ try {
47
+ const { product_id, duration } = decodeOHLCSeriesId(series_id);
48
+ const [datasource_id] = decodePath(product_id);
49
+ // 控制速率:每个数据源每秒钟只能请求一次
50
+ await tokenBucket(`backwards_target_${datasource_id}`, {
51
+ refillInterval: 1000,
52
+ capacity: 1,
53
+ }).acquire();
54
+ {
55
+ const [record] = await requestSQL(terminal, `select start_time from series_data_range where series_id = ${escapeSQL(series_id)} and table_name = 'ohlc_v2' order by start_time limit 1`);
56
+ const start_time = record ? new Date(record.start_time).getTime() : Date.now();
57
+ const req = {
58
+ product_id,
59
+ duration,
60
+ direction: 'backward',
61
+ time: start_time,
62
+ };
63
+ console.info(formatTime(Date.now()), 'DispatchIngestOHLC', `product_id=${product_id}, duration=${duration}, time=${formatTime(start_time)}`);
64
+ const res = await terminal.client.requestForResponseData('IngestOHLC', req);
65
+ terminal.metrics
66
+ .counter('series_collector_backwards_ingest_count', '')
67
+ .labels({ terminal_id: terminal.terminal_id, type: 'ohlc' })
68
+ .inc(res.wrote_count || 0);
69
+ console.info(formatTime(Date.now()), 'DispatchIngestOHLCResult', `series_id=${series_id}, ingested_count=${res.wrote_count}, start_time=${formatTime((_b = (_a = res.range) === null || _a === void 0 ? void 0 : _a.start_time) !== null && _b !== void 0 ? _b : NaN)}, end_time=${formatTime((_d = (_c = res.range) === null || _c === void 0 ? void 0 : _c.end_time) !== null && _d !== void 0 ? _d : NaN)}`);
70
+ }
71
+ }
72
+ catch (e) {
73
+ console.info(formatTime(Date.now()), 'DispatchIngestOHLCError', `series_id=${series_id}`, e);
74
+ }
75
+ }));
76
+ })
77
+ .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))
78
+ .subscribe();
79
+ //# sourceMappingURL=backwards-ohlc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["// 解决 Backwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport { decodeOHLCSeriesId, encodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport {\n IIngestOHLCRequest,\n ISeriesIngestResult,\n parseOHLCServiceMetadataFromSchema,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { defer, repeat, retry } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst listBackwardSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(terminal, `select product_id from product`);\n\n console.time('[SeriesCollector][Backwards] calc');\n\n const series_ids = new Set<string>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestOHLC') continue;\n try {\n const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);\n if (meta.direction !== 'backward') continue;\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n for (const duration of meta.duration_list) {\n const series_id = encodeOHLCSeriesId(product_id, duration);\n series_ids.add(series_id);\n }\n }\n } finally {\n }\n }\n }\n\n console.timeEnd('[SeriesCollector][Backwards] calc');\n\n return series_ids;\n};\n\ndefer(async () => {\n const time = Date.now();\n const series_ids = await listBackwardSeriesIds();\n console.log(\n `[SeriesCollector][Backwards] Found ${\n series_ids.size\n } series to collect backwards data for. (${formatTime(Date.now() - time)})`,\n );\n\n await Promise.all(\n [...series_ids].map(async (series_id) => {\n try {\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n const [datasource_id] = decodePath(product_id);\n // 控制速率:每个数据源每秒钟只能请求一次\n await tokenBucket(`backwards_target_${datasource_id}`, {\n refillInterval: 1000,\n capacity: 1,\n }).acquire();\n {\n const [record] = await requestSQL<\n {\n start_time: string;\n }[]\n >(\n terminal,\n `select start_time from series_data_range where series_id = ${escapeSQL(\n series_id,\n )} and table_name = 'ohlc_v2' order by start_time limit 1`,\n );\n const start_time = record ? new Date(record.start_time).getTime() : Date.now();\n\n const req: IIngestOHLCRequest = {\n product_id,\n duration,\n direction: 'backward',\n time: start_time,\n };\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestOHLC',\n `product_id=${product_id}, duration=${duration}, time=${formatTime(start_time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n terminal.metrics\n .counter('series_collector_backwards_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc' })\n .inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestOHLCResult',\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 } catch (e) {\n console.info(formatTime(Date.now()), 'DispatchIngestOHLCError', `series_id=${series_id}`, e);\n }\n }),\n );\n})\n .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))\n .subscribe();\n"]}
@@ -0,0 +1,3 @@
1
+ import './backwards-interest-rate';
2
+ import './backwards-ohlc';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/series-collector/index.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AACnC,OAAO,kBAAkB,CAAC","sourcesContent":["import './backwards-interest-rate';\nimport './backwards-ohlc';\n"]}
package/lib/index.d.ts CHANGED
@@ -3,4 +3,6 @@ import './general';
3
3
  import './legacy-services';
4
4
  import './product-collector';
5
5
  import './quote/service';
6
+ import './series-collector';
7
+ import './series-data';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC;AACnB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC;AACnB,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,iBAAiB,CAAC;AACzB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,eAAe,CAAC"}
package/lib/index.js CHANGED
@@ -5,4 +5,6 @@ require("./general");
5
5
  require("./legacy-services");
6
6
  require("./product-collector");
7
7
  require("./quote/service");
8
+ require("./series-collector");
9
+ require("./series-data");
8
10
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,wBAAsB;AACtB,qBAAmB;AACnB,6BAA2B;AAC3B,+BAA6B;AAC7B,2BAAyB","sourcesContent":["import './credential';\nimport './general';\nimport './legacy-services';\nimport './product-collector';\nimport './quote/service';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,wBAAsB;AACtB,qBAAmB;AACnB,6BAA2B;AAC3B,+BAA6B;AAC7B,2BAAyB;AACzB,8BAA4B;AAC5B,yBAAuB","sourcesContent":["import './credential';\nimport './general';\nimport './legacy-services';\nimport './product-collector';\nimport './quote/service';\nimport './series-collector';\nimport './series-data';\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backwards-interest-rate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-interest-rate.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ // 解决 Backwards 拉取历史数据的调度器
3
+ // 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。
4
+ // 然后对每个序列,向对应的 IngestInterestRate Service 发送拉取请求,补齐历史数据。
5
+ // 使用 Token Bucket 控制每个数据源的请求速率,避免过载。
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const exchange_1 = require("@yuants/exchange");
8
+ const protocol_1 = require("@yuants/protocol");
9
+ const sql_1 = require("@yuants/sql");
10
+ const utils_1 = require("@yuants/utils");
11
+ const rxjs_1 = require("rxjs");
12
+ const terminal = protocol_1.Terminal.fromNodeEnv();
13
+ const listBackwardSeriesIds = async () => {
14
+ const product_ids = await (0, sql_1.requestSQL)(terminal, `select product_id from product`);
15
+ console.time('[SeriesCollector][InterestRate][Backwards] calc');
16
+ const series_ids = new Set();
17
+ for (const terminalInfo of terminal.terminalInfos) {
18
+ for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {
19
+ if (serviceInfo.method !== 'IngestInterestRate')
20
+ continue;
21
+ try {
22
+ const meta = (0, exchange_1.parseInterestRateServiceMetadataFromSchema)(serviceInfo.schema);
23
+ if (meta.direction !== 'backward')
24
+ continue;
25
+ for (const { product_id } of product_ids) {
26
+ if (!product_id.startsWith(meta.product_id_prefix))
27
+ continue;
28
+ series_ids.add(product_id);
29
+ }
30
+ }
31
+ finally {
32
+ }
33
+ }
34
+ }
35
+ console.timeEnd('[SeriesCollector][InterestRate][Backwards] calc');
36
+ return series_ids;
37
+ };
38
+ (0, rxjs_1.defer)(async () => {
39
+ const time = Date.now();
40
+ const series_ids = await listBackwardSeriesIds();
41
+ console.log(`[SeriesCollector][InterestRate][Backwards] Found ${series_ids.size} series to collect backwards data for. (${(0, utils_1.formatTime)(Date.now() - time)})`);
42
+ await Promise.all([...series_ids].map(async (product_id) => {
43
+ var _a, _b, _c, _d;
44
+ try {
45
+ const [datasource_id] = (0, utils_1.decodePath)(product_id);
46
+ // 控制速率:每个数据源每秒钟只能请求一次
47
+ await (0, utils_1.tokenBucket)(`interest_rate_backwards:${datasource_id}`, {
48
+ refillInterval: 1000,
49
+ capacity: 1,
50
+ }).acquire();
51
+ {
52
+ const [record] = await (0, sql_1.requestSQL)(terminal, `select start_time from series_data_range where series_id = ${(0, sql_1.escapeSQL)(product_id)} and table_name = 'interest_rate' order by start_time limit 1`);
53
+ const start_time = record ? new Date(record.start_time).getTime() : Date.now();
54
+ const req = {
55
+ product_id: product_id,
56
+ direction: 'backward',
57
+ time: start_time,
58
+ };
59
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestInterestRateRequest', `product_id=${product_id}, time=${(0, utils_1.formatTime)(start_time)}`);
60
+ const res = await terminal.client.requestForResponseData('IngestInterestRate', req);
61
+ terminal.metrics
62
+ .counter('series_collector_backwards_ingest_count', '')
63
+ .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate' })
64
+ .inc(res.wrote_count || 0);
65
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestInterestRateResult', `series_id=${product_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)}`);
66
+ }
67
+ }
68
+ catch (e) {
69
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestInterestRateError', `series_id=${product_id}`, e);
70
+ }
71
+ }));
72
+ })
73
+ .pipe((0, rxjs_1.retry)({ delay: 1000 }), (0, rxjs_1.repeat)({ delay: 1000 }))
74
+ .subscribe();
75
+ //# sourceMappingURL=backwards-interest-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-interest-rate.js","sourceRoot":"","sources":["../../src/series-collector/backwards-interest-rate.ts"],"names":[],"mappings":"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","sourcesContent":["// 解决 Backwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestInterestRate Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport {\n IIngestInterestRateRequest,\n ISeriesIngestResult,\n parseInterestRateServiceMetadataFromSchema,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { defer, repeat, retry } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst listBackwardSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(terminal, `select product_id from product`);\n\n console.time('[SeriesCollector][InterestRate][Backwards] calc');\n\n const series_ids = new Set<string>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestInterestRate') continue;\n try {\n const meta = parseInterestRateServiceMetadataFromSchema(serviceInfo.schema);\n if (meta.direction !== 'backward') continue;\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n series_ids.add(product_id);\n }\n } finally {\n }\n }\n }\n\n console.timeEnd('[SeriesCollector][InterestRate][Backwards] calc');\n\n return series_ids;\n};\n\ndefer(async () => {\n const time = Date.now();\n const series_ids = await listBackwardSeriesIds();\n console.log(\n `[SeriesCollector][InterestRate][Backwards] Found ${\n series_ids.size\n } series to collect backwards data for. (${formatTime(Date.now() - time)})`,\n );\n\n await Promise.all(\n [...series_ids].map(async (product_id) => {\n try {\n const [datasource_id] = decodePath(product_id);\n // 控制速率:每个数据源每秒钟只能请求一次\n await tokenBucket(`interest_rate_backwards:${datasource_id}`, {\n refillInterval: 1000,\n capacity: 1,\n }).acquire();\n {\n const [record] = await requestSQL<\n {\n start_time: string;\n }[]\n >(\n terminal,\n `select start_time from series_data_range where series_id = ${escapeSQL(\n product_id,\n )} and table_name = 'interest_rate' order by start_time limit 1`,\n );\n const start_time = record ? new Date(record.start_time).getTime() : Date.now();\n\n const req: IIngestInterestRateRequest = {\n product_id: product_id,\n direction: 'backward',\n time: start_time,\n };\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestInterestRateRequest',\n `product_id=${product_id}, time=${formatTime(start_time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<\n IIngestInterestRateRequest,\n ISeriesIngestResult\n >('IngestInterestRate', req);\n\n terminal.metrics\n .counter('series_collector_backwards_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'interest_rate' })\n .inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestInterestRateResult',\n `series_id=${product_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 } catch (e) {\n console.info(formatTime(Date.now()), 'DispatchIngestInterestRateError', `series_id=${product_id}`, e);\n }\n }),\n );\n})\n .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))\n .subscribe();\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backwards-ohlc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-ohlc.d.ts","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ // 解决 Backwards 拉取历史数据的调度器
3
+ // 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。
4
+ // 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。
5
+ // 使用 Token Bucket 控制每个数据源的请求速率,避免过载。
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const data_ohlc_1 = require("@yuants/data-ohlc");
8
+ const exchange_1 = require("@yuants/exchange");
9
+ const protocol_1 = require("@yuants/protocol");
10
+ const sql_1 = require("@yuants/sql");
11
+ const utils_1 = require("@yuants/utils");
12
+ const rxjs_1 = require("rxjs");
13
+ const terminal = protocol_1.Terminal.fromNodeEnv();
14
+ const listBackwardSeriesIds = async () => {
15
+ const product_ids = await (0, sql_1.requestSQL)(terminal, `select product_id from product`);
16
+ console.time('[SeriesCollector][Backwards] calc');
17
+ const series_ids = new Set();
18
+ for (const terminalInfo of terminal.terminalInfos) {
19
+ for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {
20
+ if (serviceInfo.method !== 'IngestOHLC')
21
+ continue;
22
+ try {
23
+ const meta = (0, exchange_1.parseOHLCServiceMetadataFromSchema)(serviceInfo.schema);
24
+ if (meta.direction !== 'backward')
25
+ continue;
26
+ for (const { product_id } of product_ids) {
27
+ if (!product_id.startsWith(meta.product_id_prefix))
28
+ continue;
29
+ for (const duration of meta.duration_list) {
30
+ const series_id = (0, data_ohlc_1.encodeOHLCSeriesId)(product_id, duration);
31
+ series_ids.add(series_id);
32
+ }
33
+ }
34
+ }
35
+ finally {
36
+ }
37
+ }
38
+ }
39
+ console.timeEnd('[SeriesCollector][Backwards] calc');
40
+ return series_ids;
41
+ };
42
+ (0, rxjs_1.defer)(async () => {
43
+ const time = Date.now();
44
+ const series_ids = await listBackwardSeriesIds();
45
+ console.log(`[SeriesCollector][Backwards] Found ${series_ids.size} series to collect backwards data for. (${(0, utils_1.formatTime)(Date.now() - time)})`);
46
+ await Promise.all([...series_ids].map(async (series_id) => {
47
+ var _a, _b, _c, _d;
48
+ try {
49
+ const { product_id, duration } = (0, data_ohlc_1.decodeOHLCSeriesId)(series_id);
50
+ const [datasource_id] = (0, utils_1.decodePath)(product_id);
51
+ // 控制速率:每个数据源每秒钟只能请求一次
52
+ await (0, utils_1.tokenBucket)(`backwards_target_${datasource_id}`, {
53
+ refillInterval: 1000,
54
+ capacity: 1,
55
+ }).acquire();
56
+ {
57
+ const [record] = await (0, sql_1.requestSQL)(terminal, `select start_time from series_data_range where series_id = ${(0, sql_1.escapeSQL)(series_id)} and table_name = 'ohlc_v2' order by start_time limit 1`);
58
+ const start_time = record ? new Date(record.start_time).getTime() : Date.now();
59
+ const req = {
60
+ product_id,
61
+ duration,
62
+ direction: 'backward',
63
+ time: start_time,
64
+ };
65
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestOHLC', `product_id=${product_id}, duration=${duration}, time=${(0, utils_1.formatTime)(start_time)}`);
66
+ const res = await terminal.client.requestForResponseData('IngestOHLC', req);
67
+ terminal.metrics
68
+ .counter('series_collector_backwards_ingest_count', '')
69
+ .labels({ terminal_id: terminal.terminal_id, type: 'ohlc' })
70
+ .inc(res.wrote_count || 0);
71
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestOHLCResult', `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)}`);
72
+ }
73
+ }
74
+ catch (e) {
75
+ console.info((0, utils_1.formatTime)(Date.now()), 'DispatchIngestOHLCError', `series_id=${series_id}`, e);
76
+ }
77
+ }));
78
+ })
79
+ .pipe((0, rxjs_1.retry)({ delay: 1000 }), (0, rxjs_1.repeat)({ delay: 1000 }))
80
+ .subscribe();
81
+ //# sourceMappingURL=backwards-ohlc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backwards-ohlc.js","sourceRoot":"","sources":["../../src/series-collector/backwards-ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["// 解决 Backwards 拉取历史数据的调度器\n// 该文件会定期扫描所有 Terminal 的 ServiceInfo,提取出所有支持 Backwards 拉取的序列。\n// 然后对每个序列,向对应的 IngestOHLC Service 发送拉取请求,补齐历史数据。\n// 使用 Token Bucket 控制每个数据源的请求速率,避免过载。\n\nimport { decodeOHLCSeriesId, encodeOHLCSeriesId } from '@yuants/data-ohlc';\nimport {\n IIngestOHLCRequest,\n ISeriesIngestResult,\n parseOHLCServiceMetadataFromSchema,\n} from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { decodePath, formatTime, tokenBucket } from '@yuants/utils';\nimport { defer, repeat, retry } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst listBackwardSeriesIds = async () => {\n const product_ids = await requestSQL<{ product_id: string }[]>(terminal, `select product_id from product`);\n\n console.time('[SeriesCollector][Backwards] calc');\n\n const series_ids = new Set<string>();\n for (const terminalInfo of terminal.terminalInfos) {\n for (const serviceInfo of Object.values(terminalInfo.serviceInfo || {})) {\n if (serviceInfo.method !== 'IngestOHLC') continue;\n try {\n const meta = parseOHLCServiceMetadataFromSchema(serviceInfo.schema);\n if (meta.direction !== 'backward') continue;\n\n for (const { product_id } of product_ids) {\n if (!product_id.startsWith(meta.product_id_prefix)) continue;\n for (const duration of meta.duration_list) {\n const series_id = encodeOHLCSeriesId(product_id, duration);\n series_ids.add(series_id);\n }\n }\n } finally {\n }\n }\n }\n\n console.timeEnd('[SeriesCollector][Backwards] calc');\n\n return series_ids;\n};\n\ndefer(async () => {\n const time = Date.now();\n const series_ids = await listBackwardSeriesIds();\n console.log(\n `[SeriesCollector][Backwards] Found ${\n series_ids.size\n } series to collect backwards data for. (${formatTime(Date.now() - time)})`,\n );\n\n await Promise.all(\n [...series_ids].map(async (series_id) => {\n try {\n const { product_id, duration } = decodeOHLCSeriesId(series_id);\n const [datasource_id] = decodePath(product_id);\n // 控制速率:每个数据源每秒钟只能请求一次\n await tokenBucket(`backwards_target_${datasource_id}`, {\n refillInterval: 1000,\n capacity: 1,\n }).acquire();\n {\n const [record] = await requestSQL<\n {\n start_time: string;\n }[]\n >(\n terminal,\n `select start_time from series_data_range where series_id = ${escapeSQL(\n series_id,\n )} and table_name = 'ohlc_v2' order by start_time limit 1`,\n );\n const start_time = record ? new Date(record.start_time).getTime() : Date.now();\n\n const req: IIngestOHLCRequest = {\n product_id,\n duration,\n direction: 'backward',\n time: start_time,\n };\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestOHLC',\n `product_id=${product_id}, duration=${duration}, time=${formatTime(start_time)}`,\n );\n\n const res = await terminal.client.requestForResponseData<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n req,\n );\n\n terminal.metrics\n .counter('series_collector_backwards_ingest_count', '')\n .labels({ terminal_id: terminal.terminal_id, type: 'ohlc' })\n .inc(res.wrote_count || 0);\n\n console.info(\n formatTime(Date.now()),\n 'DispatchIngestOHLCResult',\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 } catch (e) {\n console.info(formatTime(Date.now()), 'DispatchIngestOHLCError', `series_id=${series_id}`, e);\n }\n }),\n );\n})\n .pipe(retry({ delay: 1000 }), repeat({ delay: 1000 }))\n .subscribe();\n"]}
@@ -0,0 +1,3 @@
1
+ import './backwards-interest-rate';
2
+ import './backwards-ohlc';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/series-collector/index.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AACnC,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("./backwards-interest-rate");
4
+ require("./backwards-ohlc");
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/series-collector/index.ts"],"names":[],"mappings":";;AAAA,qCAAmC;AACnC,4BAA0B","sourcesContent":["import './backwards-interest-rate';\nimport './backwards-ohlc';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/app-virtual-exchange",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "dist",
@@ -8,23 +8,22 @@
8
8
  "temp"
9
9
  ],
10
10
  "dependencies": {
11
- "@yuants/protocol": "0.53.6",
12
- "@yuants/utils": "0.18.0",
13
- "@yuants/data-product": "0.5.4",
14
- "@yuants/data-account": "0.11.3",
15
- "@yuants/data-order": "0.7.4",
16
- "@yuants/data-quote": "0.4.3",
17
- "@yuants/data-ohlc": "0.5.2",
18
- "@yuants/data-interest-rate": "0.2.2",
19
- "@yuants/secret": "0.4.4",
20
- "@yuants/sql": "0.9.34",
21
- "@yuants/exchange": "0.8.4",
22
- "@yuants/cache": "0.3.7",
11
+ "@yuants/protocol": "0.53.7",
12
+ "@yuants/utils": "0.19.0",
13
+ "@yuants/data-product": "0.5.5",
14
+ "@yuants/data-account": "0.11.4",
15
+ "@yuants/data-order": "0.7.5",
16
+ "@yuants/data-quote": "0.4.4",
17
+ "@yuants/data-ohlc": "0.5.3",
18
+ "@yuants/data-interest-rate": "0.2.3",
19
+ "@yuants/secret": "0.4.5",
20
+ "@yuants/sql": "0.9.35",
21
+ "@yuants/exchange": "0.8.5",
22
+ "@yuants/cache": "0.3.8",
23
23
  "rxjs": "~7.5.6",
24
24
  "ajv": "~8.12.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@microsoft/api-extractor": "~7.30.0",
28
27
  "@rushstack/heft": "~0.47.5",
29
28
  "@rushstack/heft-jest-plugin": "~0.16.8",
30
29
  "@rushstack/heft-node-rig": "~1.10.7",
@@ -38,6 +37,7 @@
38
37
  "registry": "https://registry.npmjs.org"
39
38
  },
40
39
  "scripts": {
41
- "build": "heft test --clean && api-extractor run --local && yuan-toolkit post-build"
40
+ "build": "heft test --clean",
41
+ "test": "heft test --clean"
42
42
  }
43
43
  }
@@ -1 +0,0 @@
1
- export { }
@@ -1,11 +0,0 @@
1
- // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
- // It should be published with your NPM package. It should not be tracked by Git.
3
- {
4
- "tsdocVersion": "0.12",
5
- "toolPackages": [
6
- {
7
- "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.30.1"
9
- }
10
- ]
11
- }
@@ -1,177 +0,0 @@
1
- {
2
- "metadata": {
3
- "toolPackage": "@microsoft/api-extractor",
4
- "toolVersion": "7.30.1",
5
- "schemaVersion": 1009,
6
- "oldestForwardsCompatibleVersion": 1001,
7
- "tsdocConfig": {
8
- "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
9
- "noStandardTags": true,
10
- "tagDefinitions": [
11
- {
12
- "tagName": "@alpha",
13
- "syntaxKind": "modifier"
14
- },
15
- {
16
- "tagName": "@beta",
17
- "syntaxKind": "modifier"
18
- },
19
- {
20
- "tagName": "@defaultValue",
21
- "syntaxKind": "block"
22
- },
23
- {
24
- "tagName": "@decorator",
25
- "syntaxKind": "block",
26
- "allowMultiple": true
27
- },
28
- {
29
- "tagName": "@deprecated",
30
- "syntaxKind": "block"
31
- },
32
- {
33
- "tagName": "@eventProperty",
34
- "syntaxKind": "modifier"
35
- },
36
- {
37
- "tagName": "@example",
38
- "syntaxKind": "block",
39
- "allowMultiple": true
40
- },
41
- {
42
- "tagName": "@experimental",
43
- "syntaxKind": "modifier"
44
- },
45
- {
46
- "tagName": "@inheritDoc",
47
- "syntaxKind": "inline"
48
- },
49
- {
50
- "tagName": "@internal",
51
- "syntaxKind": "modifier"
52
- },
53
- {
54
- "tagName": "@label",
55
- "syntaxKind": "inline"
56
- },
57
- {
58
- "tagName": "@link",
59
- "syntaxKind": "inline",
60
- "allowMultiple": true
61
- },
62
- {
63
- "tagName": "@override",
64
- "syntaxKind": "modifier"
65
- },
66
- {
67
- "tagName": "@packageDocumentation",
68
- "syntaxKind": "modifier"
69
- },
70
- {
71
- "tagName": "@param",
72
- "syntaxKind": "block",
73
- "allowMultiple": true
74
- },
75
- {
76
- "tagName": "@privateRemarks",
77
- "syntaxKind": "block"
78
- },
79
- {
80
- "tagName": "@public",
81
- "syntaxKind": "modifier"
82
- },
83
- {
84
- "tagName": "@readonly",
85
- "syntaxKind": "modifier"
86
- },
87
- {
88
- "tagName": "@remarks",
89
- "syntaxKind": "block"
90
- },
91
- {
92
- "tagName": "@returns",
93
- "syntaxKind": "block"
94
- },
95
- {
96
- "tagName": "@sealed",
97
- "syntaxKind": "modifier"
98
- },
99
- {
100
- "tagName": "@see",
101
- "syntaxKind": "block"
102
- },
103
- {
104
- "tagName": "@throws",
105
- "syntaxKind": "block",
106
- "allowMultiple": true
107
- },
108
- {
109
- "tagName": "@typeParam",
110
- "syntaxKind": "block",
111
- "allowMultiple": true
112
- },
113
- {
114
- "tagName": "@virtual",
115
- "syntaxKind": "modifier"
116
- },
117
- {
118
- "tagName": "@betaDocumentation",
119
- "syntaxKind": "modifier"
120
- },
121
- {
122
- "tagName": "@internalRemarks",
123
- "syntaxKind": "block"
124
- },
125
- {
126
- "tagName": "@preapproved",
127
- "syntaxKind": "modifier"
128
- }
129
- ],
130
- "supportForTags": {
131
- "@alpha": true,
132
- "@beta": true,
133
- "@defaultValue": true,
134
- "@decorator": true,
135
- "@deprecated": true,
136
- "@eventProperty": true,
137
- "@example": true,
138
- "@experimental": true,
139
- "@inheritDoc": true,
140
- "@internal": true,
141
- "@label": true,
142
- "@link": true,
143
- "@override": true,
144
- "@packageDocumentation": true,
145
- "@param": true,
146
- "@privateRemarks": true,
147
- "@public": true,
148
- "@readonly": true,
149
- "@remarks": true,
150
- "@returns": true,
151
- "@sealed": true,
152
- "@see": true,
153
- "@throws": true,
154
- "@typeParam": true,
155
- "@virtual": true,
156
- "@betaDocumentation": true,
157
- "@internalRemarks": true,
158
- "@preapproved": true
159
- },
160
- "reportUnsupportedHtmlElements": false
161
- }
162
- },
163
- "kind": "Package",
164
- "canonicalReference": "@yuants/app-virtual-exchange!",
165
- "docComment": "",
166
- "name": "@yuants/app-virtual-exchange",
167
- "preserveMemberOrder": false,
168
- "members": [
169
- {
170
- "kind": "EntryPoint",
171
- "canonicalReference": "@yuants/app-virtual-exchange!",
172
- "name": "",
173
- "preserveMemberOrder": false,
174
- "members": []
175
- }
176
- ]
177
- }
@@ -1,9 +0,0 @@
1
- ## API Report File for "@yuants/app-virtual-exchange"
2
-
3
- > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4
-
5
- ```ts
6
-
7
- // (No @packageDocumentation comment for this package)
8
-
9
- ```
@@ -1,56 +0,0 @@
1
- {
2
- "apps/virtual-exchange/CHANGELOG.json": "56f09e32570267db12d422f9da8d2772a991b4ca",
3
- "apps/virtual-exchange/CHANGELOG.md": "12dc1066fb7efc39680f463dd4ad69288b46102a",
4
- "apps/virtual-exchange/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
5
- "apps/virtual-exchange/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
6
- "apps/virtual-exchange/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
7
- "apps/virtual-exchange/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
8
- "apps/virtual-exchange/etc/app-virtual-exchange.api.md": "6cb40ec1fa2d40a31a7b0dd3f02b8b24a4d7c4de",
9
- "apps/virtual-exchange/package.json": "16e48b1bbf511fb601cc40544613f9bea2c0f152",
10
- "apps/virtual-exchange/src/credential.ts": "7ff9cfe06e46005b2a69e60b5596eb1f59d42bba",
11
- "apps/virtual-exchange/src/general.ts": "b3d0cd8c57975b9711008beaa05ad7f6812bd57e",
12
- "apps/virtual-exchange/src/index.ts": "67e1963facf0ee2aedd871496361cff90bf49356",
13
- "apps/virtual-exchange/src/legacy-services.ts": "a9f6b6c61b7a0efc909a443e6fde88c2766562bf",
14
- "apps/virtual-exchange/src/position.ts": "df2e7fc833bad109c4939df9535577995179120f",
15
- "apps/virtual-exchange/src/product-collector.ts": "15ba0a692d694d20b607eaad0287a864577ef30c",
16
- "apps/virtual-exchange/src/quote/DESIGN.md": "4b952e24f77a7429fd82cdf29155a725bbebe583",
17
- "apps/virtual-exchange/src/quote/QUOTE_STATE_PERFORMANCE_REPORT.md": "b90b7b77a70bb5f4b503d03ccba8f1d07edf7d37",
18
- "apps/virtual-exchange/src/quote/__tests__/implementations.test.ts": "2ab7a385eaffe344d5ebfc87689399c096831b54",
19
- "apps/virtual-exchange/src/quote/benchmark/ForkedQuoteStateComparisonTest.ts": "de83e52651e4ca3a330719e805298af3f195c696",
20
- "apps/virtual-exchange/src/quote/benchmark/PerformanceTester.ts": "5de2f97bf856804bb98309939dab273334b373cc",
21
- "apps/virtual-exchange/src/quote/benchmark/QuoteStateComparisonTest.ts": "1d9c11444333d6a27898d6c1209b1b84d37a9bab",
22
- "apps/virtual-exchange/src/quote/benchmark/QuoteStateTestRunner.ts": "f7ef7815f7f3dd601aa22e8eb20aa0111ce59e17",
23
- "apps/virtual-exchange/src/quote/benchmark/index.ts": "a3049b3d2bb05461abfcc442b63fbc81d032496a",
24
- "apps/virtual-exchange/src/quote/benchmark/test-helpers.ts": "2f24c0bb8c9e92fb06ab3a5fdf8e7d5d999894f3",
25
- "apps/virtual-exchange/src/quote/benchmark/worker.ts": "936e4332139e15d1278fcefaf0bb0c5fb66a38d2",
26
- "apps/virtual-exchange/src/quote/implementations/README.md": "da3afe60c9bc16576cc226d63c233bb2d2fd7c38",
27
- "apps/virtual-exchange/src/quote/implementations/index.ts": "99d8c99b24e5e7f14293f489916c83a0bac192d7",
28
- "apps/virtual-exchange/src/quote/implementations/v0.ts": "cbc6aa7b7356b18d83a219241e9070e2aeed1365",
29
- "apps/virtual-exchange/src/quote/implementations/v1.ts": "4ae86c1d5d8dc39c1c1fc695d6990d859e2c2137",
30
- "apps/virtual-exchange/src/quote/implementations/v2.ts": "8723cede6cee6092ec0b8ce9b273ee92f47790cf",
31
- "apps/virtual-exchange/src/quote/implementations/v3.ts": "f5e4f31c5592d84206d0a27ee51107ba9a91a53d",
32
- "apps/virtual-exchange/src/quote/scheduler.ts": "d92a25ed63098a5536b7957f4e98bd1c009843c8",
33
- "apps/virtual-exchange/src/quote/service.ts": "dd32a7af1aa58b388bcfadfe81b605b646a9b0eb",
34
- "apps/virtual-exchange/src/quote/state.benchmark.ts": "075d3c5bab0ae6f7b61accfe977f7d35233b06ad",
35
- "apps/virtual-exchange/src/quote/state.ts": "8690d156db5850cde46c366a884d6fc707dc3b7c",
36
- "apps/virtual-exchange/src/quote/types.ts": "4894fd3df8b5bb92e7aaacda9136fa3e70d45835",
37
- "apps/virtual-exchange/src/series-data/DESIGN.md": "234bdf976d858b600ac1d08112da1ad867431bfb",
38
- "apps/virtual-exchange/src/series-data/fifo-queue.ts": "dfe554dbb36142949bab25705ebefbb2383d613a",
39
- "apps/virtual-exchange/src/series-data/index.ts": "e441a01409f67aea91e9cf84665bfe6afb4a4e32",
40
- "apps/virtual-exchange/src/series-data/scheduler.ts": "6a6ca452acdd8ca27848f65245ab0152c8ba098e",
41
- "apps/virtual-exchange/tsconfig.json": "22f94ca28b507f8ddcc21b9053158eefd3f726a9",
42
- "apps/virtual-exchange/.rush/temp/shrinkwrap-deps.json": "deae9008e3c44e2cebc6f5c3c301b2e0ba45555e",
43
- "libraries/protocol/temp/package-deps.json": "ad2b09da06aa0b6d98e9ca145c3da7c8418f30d1",
44
- "libraries/utils/temp/package-deps.json": "6afd4e6b9f8348c0c24e05f7289101fc6b8fa5a9",
45
- "libraries/data-product/temp/package-deps.json": "77b545e27fbd147bf5fded94beb5baaa33687563",
46
- "libraries/data-account/temp/package-deps.json": "ec07276e124d707820e348948c8689cd4b4d5a84",
47
- "libraries/data-order/temp/package-deps.json": "d2826719d6e1f86ad64cfe6556a0f61352e02897",
48
- "libraries/data-quote/temp/package-deps.json": "5aa2671e9a9e7b94827a8891049c4af5eefe757e",
49
- "libraries/data-ohlc/temp/package-deps.json": "f6a0a2248e237fe960daf27c93071ec1c3235fa3",
50
- "libraries/data-interest-rate/temp/package-deps.json": "d1a26e2ed8d3ecd147e0b3a897927720d7760597",
51
- "libraries/secret/temp/package-deps.json": "3dc2808f0b7de3ab417aa1302a5587f5d1c0ba46",
52
- "libraries/sql/temp/package-deps.json": "1fb8bcfa1bd3912150e7567770b065794a3b2138",
53
- "libraries/exchange/temp/package-deps.json": "8315951811f0278801081fe8e48ba07213af6816",
54
- "libraries/cache/temp/package-deps.json": "8faf993aa54072a8cc7773ca9502618ec1660be1",
55
- "tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
56
- }