@yuants/vendor-trading-view 0.1.43 → 0.2.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/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import './index';
3
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
@@ -0,0 +1,105 @@
1
+ import { makeDockerEnvs, makeK8sEnvs } from '@yuants/extension';
2
+ export default (context) => {
3
+ const COMPONENT_NAME = 'vendor-trading-view';
4
+ context.registerDeployProvider({
5
+ make_json_schema: () => ({
6
+ type: 'object',
7
+ properties: {
8
+ env: {
9
+ type: 'object',
10
+ required: ['HOST_URL'],
11
+ properties: {
12
+ HOST_URL: {
13
+ type: 'string',
14
+ title: '主机地址',
15
+ },
16
+ CONCURRENCY: {
17
+ type: 'number',
18
+ title: '拉取数据并发量',
19
+ },
20
+ LOG_LEVEL: {
21
+ type: 'string',
22
+ enum: ['INFO', 'DEBUG'],
23
+ },
24
+ },
25
+ },
26
+ },
27
+ }),
28
+ make_docker_compose_file: async (ctx, envCtx) => {
29
+ var _a;
30
+ return {
31
+ [COMPONENT_NAME.replace(/\s/g, '')]: {
32
+ image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${(_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version}`,
33
+ restart: 'always',
34
+ environment: makeDockerEnvs(ctx.env),
35
+ },
36
+ };
37
+ },
38
+ make_k8s_resource_objects: async (ctx, envCtx) => {
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
40
+ const manifest_key = ctx.key;
41
+ return {
42
+ deployment: {
43
+ apiVersion: 'apps/v1',
44
+ kind: 'Deployment',
45
+ metadata: {
46
+ labels: {
47
+ 'y.ntnl.io/version': (_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version,
48
+ 'y.ntnl.io/component': COMPONENT_NAME,
49
+ 'y.ntnl.io/manifest-key': manifest_key,
50
+ },
51
+ name: COMPONENT_NAME.replace(/\s/g, '').toLocaleLowerCase(),
52
+ namespace: 'yuan',
53
+ },
54
+ spec: {
55
+ replicas: 1,
56
+ selector: {
57
+ matchLabels: {
58
+ 'y.ntnl.io/component': COMPONENT_NAME,
59
+ 'y.ntnl.io/manifest-key': manifest_key,
60
+ },
61
+ },
62
+ template: {
63
+ metadata: {
64
+ labels: {
65
+ 'y.ntnl.io/version': (_b = ctx.version) !== null && _b !== void 0 ? _b : envCtx.version,
66
+ 'y.ntnl.io/component': COMPONENT_NAME,
67
+ 'y.ntnl.io/manifest-key': manifest_key,
68
+ },
69
+ },
70
+ spec: {
71
+ containers: [
72
+ {
73
+ command: ['node'],
74
+ args: ['lib/index.js'],
75
+ env: makeK8sEnvs(ctx.env),
76
+ image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${(_c = ctx.version) !== null && _c !== void 0 ? _c : envCtx.version}`,
77
+ imagePullPolicy: 'IfNotPresent',
78
+ name: COMPONENT_NAME,
79
+ resources: {
80
+ limits: {
81
+ cpu: (_e = (_d = ctx.cpu) === null || _d === void 0 ? void 0 : _d.max) !== null && _e !== void 0 ? _e : '500m',
82
+ memory: (_g = (_f = ctx.memory) === null || _f === void 0 ? void 0 : _f.max) !== null && _g !== void 0 ? _g : '512Mi',
83
+ },
84
+ requests: {
85
+ cpu: (_j = (_h = ctx.cpu) === null || _h === void 0 ? void 0 : _h.min) !== null && _j !== void 0 ? _j : '250m',
86
+ memory: (_l = (_k = ctx.memory) === null || _k === void 0 ? void 0 : _k.min) !== null && _l !== void 0 ? _l : '256Mi',
87
+ },
88
+ },
89
+ },
90
+ ],
91
+ hostname: COMPONENT_NAME,
92
+ imagePullSecrets: [
93
+ {
94
+ name: 'pull-secret',
95
+ },
96
+ ],
97
+ },
98
+ },
99
+ },
100
+ },
101
+ };
102
+ },
103
+ });
104
+ };
105
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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","sourcesContent":["import { IExtensionContext, makeDockerEnvs, makeK8sEnvs } from '@yuants/extension';\nexport default (context: IExtensionContext) => {\n const COMPONENT_NAME = 'vendor-trading-view';\n context.registerDeployProvider({\n make_json_schema: () => ({\n type: 'object',\n properties: {\n env: {\n type: 'object',\n required: ['HOST_URL'],\n properties: {\n HOST_URL: {\n type: 'string',\n title: '主机地址',\n },\n CONCURRENCY: {\n type: 'number',\n title: '拉取数据并发量',\n },\n LOG_LEVEL: {\n type: 'string',\n enum: ['INFO', 'DEBUG'],\n },\n },\n },\n },\n }),\n make_docker_compose_file: async (ctx, envCtx) => {\n return {\n [COMPONENT_NAME.replace(/\\s/g, '')]: {\n image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${ctx.version ?? envCtx.version}`,\n restart: 'always',\n environment: makeDockerEnvs(ctx.env),\n },\n };\n },\n make_k8s_resource_objects: async (ctx, envCtx) => {\n const manifest_key = ctx.key;\n return {\n deployment: {\n apiVersion: 'apps/v1',\n kind: 'Deployment',\n metadata: {\n labels: {\n 'y.ntnl.io/version': ctx.version ?? envCtx.version,\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n name: COMPONENT_NAME.replace(/\\s/g, '').toLocaleLowerCase(),\n namespace: 'yuan',\n },\n spec: {\n replicas: 1,\n selector: {\n matchLabels: {\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n },\n template: {\n metadata: {\n labels: {\n 'y.ntnl.io/version': ctx.version ?? envCtx.version,\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n },\n spec: {\n containers: [\n {\n command: ['node'],\n args: ['lib/index.js'],\n env: makeK8sEnvs(ctx.env),\n image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${ctx.version ?? envCtx.version}`,\n imagePullPolicy: 'IfNotPresent',\n name: COMPONENT_NAME,\n resources: {\n limits: {\n cpu: ctx.cpu?.max ?? '500m',\n memory: ctx.memory?.max ?? '512Mi',\n },\n requests: {\n cpu: ctx.cpu?.min ?? '250m',\n memory: ctx.memory?.min ?? '256Mi',\n },\n },\n },\n ],\n hostname: COMPONENT_NAME,\n imagePullSecrets: [\n {\n name: 'pull-secret',\n },\n ],\n },\n },\n },\n },\n };\n },\n });\n};\n"]}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ import { createSeriesProvider } from '@yuants/data-series';
2
+ import { Terminal } from '@yuants/protocol';
3
+ import { convertDurationToOffset, decodePath, formatTime } from '@yuants/utils';
4
+ import { Observable, firstValueFrom } from 'rxjs';
5
+ //@ts-ignore
6
+ import TradingView from '@mathieuc/tradingview';
7
+ const terminal = Terminal.fromNodeEnv();
8
+ const DURATION_TO_TRADINGVIEW_PERIOD = {
9
+ PT1M: '1',
10
+ PT3M: '3',
11
+ PT5M: '5',
12
+ PT15M: '15',
13
+ PT30M: '30',
14
+ PT45M: '45',
15
+ PT1H: '60',
16
+ PT2H: '120',
17
+ PT3H: '180',
18
+ PT4H: '240',
19
+ P1D: '1D',
20
+ P1W: '1W',
21
+ P1M: '1M',
22
+ P3M: '3M',
23
+ P6M: '6M',
24
+ P1Y: '12M',
25
+ };
26
+ createSeriesProvider(terminal, {
27
+ tableName: 'ohlc',
28
+ series_id_prefix_parts: ['TradingView'],
29
+ reversed: false,
30
+ serviceOptions: { concurrent: +(process.env.CONCURRENCY || 2) },
31
+ queryFn: async ({ series_id, started_at, ended_at }) => {
32
+ const [datasource_id, product_id, duration] = decodePath(series_id);
33
+ const offset = convertDurationToOffset(duration);
34
+ if (!offset)
35
+ throw new Error(`Unsupported duration: ${duration}`);
36
+ const timeframe = DURATION_TO_TRADINGVIEW_PERIOD[duration];
37
+ if (!timeframe)
38
+ throw new Error(`Unsupported timeframe: ${duration}`);
39
+ const range = Math.ceil((ended_at - started_at) / offset);
40
+ if (range <= 0) {
41
+ throw `range=${range} is invalid`;
42
+ }
43
+ console.info(formatTime(Date.now()), 'queryChartRequest', JSON.stringify({ series_id, product_id, duration, range }));
44
+ const data = await firstValueFrom(new Observable((subscriber) => {
45
+ const client = new TradingView.Client();
46
+ const chart = new client.Session.Chart();
47
+ chart.setMarket(product_id, {
48
+ timeframe,
49
+ range,
50
+ to: ended_at,
51
+ });
52
+ chart.onError((e) => {
53
+ subscriber.error(e);
54
+ });
55
+ chart.onUpdate(() => {
56
+ const rawPeriods = chart.periods;
57
+ if (rawPeriods.length !== 0) {
58
+ const periods = rawPeriods.map((v) => ({
59
+ series_id,
60
+ created_at: formatTime(v.time * 1000),
61
+ datasource_id,
62
+ product_id,
63
+ duration,
64
+ closed_at: formatTime(v.time * 1000 + offset),
65
+ open: `${v.open}`,
66
+ high: `${v.max}`,
67
+ low: `${v.min}`,
68
+ close: `${v.close}`,
69
+ volume: `${v.volume}`,
70
+ open_interest: '0',
71
+ }));
72
+ subscriber.next(periods);
73
+ subscriber.complete();
74
+ }
75
+ });
76
+ return () => {
77
+ client.end();
78
+ };
79
+ }));
80
+ console.info(formatTime(Date.now()), 'queryChartResponse', JSON.stringify({
81
+ series_id,
82
+ product_id,
83
+ duration,
84
+ data_length: data.length,
85
+ }));
86
+ return data;
87
+ },
88
+ });
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, formatTime } from '@yuants/utils';\nimport { Observable, firstValueFrom } from 'rxjs';\n//@ts-ignore\nimport TradingView from '@mathieuc/tradingview';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst DURATION_TO_TRADINGVIEW_PERIOD: Record<string, string> = {\n PT1M: '1',\n PT3M: '3',\n PT5M: '5',\n PT15M: '15',\n PT30M: '30',\n PT45M: '45',\n PT1H: '60',\n PT2H: '120',\n PT3H: '180',\n PT4H: '240',\n P1D: '1D',\n P1W: '1W',\n P1M: '1M',\n P3M: '3M',\n P6M: '6M',\n P1Y: '12M',\n};\n\ncreateSeriesProvider(terminal, {\n tableName: 'ohlc',\n series_id_prefix_parts: ['TradingView'],\n reversed: false,\n serviceOptions: { concurrent: +(process.env.CONCURRENCY || 2) },\n queryFn: async ({ series_id, started_at, ended_at }) => {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const offset = convertDurationToOffset(duration);\n if (!offset) throw new Error(`Unsupported duration: ${duration}`);\n\n const timeframe = DURATION_TO_TRADINGVIEW_PERIOD[duration];\n if (!timeframe) throw new Error(`Unsupported timeframe: ${duration}`);\n\n const range = Math.ceil((ended_at - started_at) / offset);\n if (range <= 0) {\n throw `range=${range} is invalid`;\n }\n\n console.info(\n formatTime(Date.now()),\n 'queryChartRequest',\n JSON.stringify({ series_id, product_id, duration, range }),\n );\n\n const data = await firstValueFrom(\n new Observable<IOHLC[]>((subscriber) => {\n const client = new TradingView.Client();\n const chart = new client.Session.Chart();\n chart.setMarket(product_id, {\n timeframe,\n range,\n to: ended_at,\n });\n chart.onError((e: any) => {\n subscriber.error(e);\n });\n chart.onUpdate(() => {\n const rawPeriods: any[] = chart.periods;\n if (rawPeriods.length !== 0) {\n const periods = rawPeriods.map(\n (v): IOHLC => ({\n series_id,\n created_at: formatTime(v.time * 1000),\n datasource_id,\n product_id,\n duration,\n closed_at: formatTime(v.time * 1000 + offset),\n open: `${v.open}`,\n high: `${v.max}`,\n low: `${v.min}`,\n close: `${v.close}`,\n volume: `${v.volume}`,\n open_interest: '0',\n }),\n );\n subscriber.next(periods);\n subscriber.complete();\n }\n });\n return () => {\n client.end();\n };\n }),\n );\n\n console.info(\n formatTime(Date.now()),\n 'queryChartResponse',\n JSON.stringify({\n series_id,\n product_id,\n duration,\n data_length: data.length,\n }),\n );\n\n return data;\n },\n});\n"]}
@@ -0,0 +1 @@
1
+ export { }
package/lib/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import './index';
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,SAAS,CAAC"}
package/lib/cli.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ require("./index");
5
+ //# sourceMappingURL=cli.js.map
package/lib/cli.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA,mBAAiB","sourcesContent":["#!/usr/bin/env node\nimport './index';\n"]}
@@ -0,0 +1,4 @@
1
+ import { IExtensionContext } from '@yuants/extension';
2
+ declare const _default: (context: IExtensionContext) => void;
3
+ export default _default;
4
+ //# sourceMappingURL=extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA+B,MAAM,mBAAmB,CAAC;kCAC1D,iBAAiB;AAA1C,wBAoGE"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const extension_1 = require("@yuants/extension");
4
+ exports.default = (context) => {
5
+ const COMPONENT_NAME = 'vendor-trading-view';
6
+ context.registerDeployProvider({
7
+ make_json_schema: () => ({
8
+ type: 'object',
9
+ properties: {
10
+ env: {
11
+ type: 'object',
12
+ required: ['HOST_URL'],
13
+ properties: {
14
+ HOST_URL: {
15
+ type: 'string',
16
+ title: '主机地址',
17
+ },
18
+ CONCURRENCY: {
19
+ type: 'number',
20
+ title: '拉取数据并发量',
21
+ },
22
+ LOG_LEVEL: {
23
+ type: 'string',
24
+ enum: ['INFO', 'DEBUG'],
25
+ },
26
+ },
27
+ },
28
+ },
29
+ }),
30
+ make_docker_compose_file: async (ctx, envCtx) => {
31
+ var _a;
32
+ return {
33
+ [COMPONENT_NAME.replace(/\s/g, '')]: {
34
+ image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${(_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version}`,
35
+ restart: 'always',
36
+ environment: (0, extension_1.makeDockerEnvs)(ctx.env),
37
+ },
38
+ };
39
+ },
40
+ make_k8s_resource_objects: async (ctx, envCtx) => {
41
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
42
+ const manifest_key = ctx.key;
43
+ return {
44
+ deployment: {
45
+ apiVersion: 'apps/v1',
46
+ kind: 'Deployment',
47
+ metadata: {
48
+ labels: {
49
+ 'y.ntnl.io/version': (_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version,
50
+ 'y.ntnl.io/component': COMPONENT_NAME,
51
+ 'y.ntnl.io/manifest-key': manifest_key,
52
+ },
53
+ name: COMPONENT_NAME.replace(/\s/g, '').toLocaleLowerCase(),
54
+ namespace: 'yuan',
55
+ },
56
+ spec: {
57
+ replicas: 1,
58
+ selector: {
59
+ matchLabels: {
60
+ 'y.ntnl.io/component': COMPONENT_NAME,
61
+ 'y.ntnl.io/manifest-key': manifest_key,
62
+ },
63
+ },
64
+ template: {
65
+ metadata: {
66
+ labels: {
67
+ 'y.ntnl.io/version': (_b = ctx.version) !== null && _b !== void 0 ? _b : envCtx.version,
68
+ 'y.ntnl.io/component': COMPONENT_NAME,
69
+ 'y.ntnl.io/manifest-key': manifest_key,
70
+ },
71
+ },
72
+ spec: {
73
+ containers: [
74
+ {
75
+ command: ['node'],
76
+ args: ['lib/index.js'],
77
+ env: (0, extension_1.makeK8sEnvs)(ctx.env),
78
+ image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${(_c = ctx.version) !== null && _c !== void 0 ? _c : envCtx.version}`,
79
+ imagePullPolicy: 'IfNotPresent',
80
+ name: COMPONENT_NAME,
81
+ resources: {
82
+ limits: {
83
+ cpu: (_e = (_d = ctx.cpu) === null || _d === void 0 ? void 0 : _d.max) !== null && _e !== void 0 ? _e : '500m',
84
+ memory: (_g = (_f = ctx.memory) === null || _f === void 0 ? void 0 : _f.max) !== null && _g !== void 0 ? _g : '512Mi',
85
+ },
86
+ requests: {
87
+ cpu: (_j = (_h = ctx.cpu) === null || _h === void 0 ? void 0 : _h.min) !== null && _j !== void 0 ? _j : '250m',
88
+ memory: (_l = (_k = ctx.memory) === null || _k === void 0 ? void 0 : _k.min) !== null && _l !== void 0 ? _l : '256Mi',
89
+ },
90
+ },
91
+ },
92
+ ],
93
+ hostname: COMPONENT_NAME,
94
+ imagePullSecrets: [
95
+ {
96
+ name: 'pull-secret',
97
+ },
98
+ ],
99
+ },
100
+ },
101
+ },
102
+ },
103
+ };
104
+ },
105
+ });
106
+ };
107
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;AAAA,iDAAmF;AACnF,kBAAe,CAAC,OAA0B,EAAE,EAAE;IAC5C,MAAM,cAAc,GAAG,qBAAqB,CAAC;IAC7C,OAAO,CAAC,sBAAsB,CAAC;QAC7B,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,QAAQ,EAAE,CAAC,UAAU,CAAC;oBACtB,UAAU,EAAE;wBACV,QAAQ,EAAE;4BACR,IAAI,EAAE,QAAQ;4BACd,KAAK,EAAE,MAAM;yBACd;wBACD,WAAW,EAAE;4BACX,IAAI,EAAE,QAAQ;4BACd,KAAK,EAAE,SAAS;yBACjB;wBACD,SAAS,EAAE;4BACT,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;yBACxB;qBACF;iBACF;aACF;SACF,CAAC;QACF,wBAAwB,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;;YAC9C,OAAO;gBACL,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE;oBACnC,KAAK,EAAE,4BAA4B,cAAc,IAAI,MAAA,GAAG,CAAC,OAAO,mCAAI,MAAM,CAAC,OAAO,EAAE;oBACpF,OAAO,EAAE,QAAQ;oBACjB,WAAW,EAAE,IAAA,0BAAc,EAAC,GAAG,CAAC,GAAG,CAAC;iBACrC;aACF,CAAC;QACJ,CAAC;QACD,yBAAyB,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;;YAC/C,MAAM,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC;YAC7B,OAAO;gBACL,UAAU,EAAE;oBACV,UAAU,EAAE,SAAS;oBACrB,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE;wBACR,MAAM,EAAE;4BACN,mBAAmB,EAAE,MAAA,GAAG,CAAC,OAAO,mCAAI,MAAM,CAAC,OAAO;4BAClD,qBAAqB,EAAE,cAAc;4BACrC,wBAAwB,EAAE,YAAY;yBACvC;wBACD,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,iBAAiB,EAAE;wBAC3D,SAAS,EAAE,MAAM;qBAClB;oBACD,IAAI,EAAE;wBACJ,QAAQ,EAAE,CAAC;wBACX,QAAQ,EAAE;4BACR,WAAW,EAAE;gCACX,qBAAqB,EAAE,cAAc;gCACrC,wBAAwB,EAAE,YAAY;6BACvC;yBACF;wBACD,QAAQ,EAAE;4BACR,QAAQ,EAAE;gCACR,MAAM,EAAE;oCACN,mBAAmB,EAAE,MAAA,GAAG,CAAC,OAAO,mCAAI,MAAM,CAAC,OAAO;oCAClD,qBAAqB,EAAE,cAAc;oCACrC,wBAAwB,EAAE,YAAY;iCACvC;6BACF;4BACD,IAAI,EAAE;gCACJ,UAAU,EAAE;oCACV;wCACE,OAAO,EAAE,CAAC,MAAM,CAAC;wCACjB,IAAI,EAAE,CAAC,cAAc,CAAC;wCACtB,GAAG,EAAE,IAAA,uBAAW,EAAC,GAAG,CAAC,GAAG,CAAC;wCACzB,KAAK,EAAE,4BAA4B,cAAc,IAAI,MAAA,GAAG,CAAC,OAAO,mCAAI,MAAM,CAAC,OAAO,EAAE;wCACpF,eAAe,EAAE,cAAc;wCAC/B,IAAI,EAAE,cAAc;wCACpB,SAAS,EAAE;4CACT,MAAM,EAAE;gDACN,GAAG,EAAE,MAAA,MAAA,GAAG,CAAC,GAAG,0CAAE,GAAG,mCAAI,MAAM;gDAC3B,MAAM,EAAE,MAAA,MAAA,GAAG,CAAC,MAAM,0CAAE,GAAG,mCAAI,OAAO;6CACnC;4CACD,QAAQ,EAAE;gDACR,GAAG,EAAE,MAAA,MAAA,GAAG,CAAC,GAAG,0CAAE,GAAG,mCAAI,MAAM;gDAC3B,MAAM,EAAE,MAAA,MAAA,GAAG,CAAC,MAAM,0CAAE,GAAG,mCAAI,OAAO;6CACnC;yCACF;qCACF;iCACF;gCACD,QAAQ,EAAE,cAAc;gCACxB,gBAAgB,EAAE;oCAChB;wCACE,IAAI,EAAE,aAAa;qCACpB;iCACF;6BACF;yBACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { IExtensionContext, makeDockerEnvs, makeK8sEnvs } from '@yuants/extension';\nexport default (context: IExtensionContext) => {\n const COMPONENT_NAME = 'vendor-trading-view';\n context.registerDeployProvider({\n make_json_schema: () => ({\n type: 'object',\n properties: {\n env: {\n type: 'object',\n required: ['HOST_URL'],\n properties: {\n HOST_URL: {\n type: 'string',\n title: '主机地址',\n },\n CONCURRENCY: {\n type: 'number',\n title: '拉取数据并发量',\n },\n LOG_LEVEL: {\n type: 'string',\n enum: ['INFO', 'DEBUG'],\n },\n },\n },\n },\n }),\n make_docker_compose_file: async (ctx, envCtx) => {\n return {\n [COMPONENT_NAME.replace(/\\s/g, '')]: {\n image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${ctx.version ?? envCtx.version}`,\n restart: 'always',\n environment: makeDockerEnvs(ctx.env),\n },\n };\n },\n make_k8s_resource_objects: async (ctx, envCtx) => {\n const manifest_key = ctx.key;\n return {\n deployment: {\n apiVersion: 'apps/v1',\n kind: 'Deployment',\n metadata: {\n labels: {\n 'y.ntnl.io/version': ctx.version ?? envCtx.version,\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n name: COMPONENT_NAME.replace(/\\s/g, '').toLocaleLowerCase(),\n namespace: 'yuan',\n },\n spec: {\n replicas: 1,\n selector: {\n matchLabels: {\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n },\n template: {\n metadata: {\n labels: {\n 'y.ntnl.io/version': ctx.version ?? envCtx.version,\n 'y.ntnl.io/component': COMPONENT_NAME,\n 'y.ntnl.io/manifest-key': manifest_key,\n },\n },\n spec: {\n containers: [\n {\n command: ['node'],\n args: ['lib/index.js'],\n env: makeK8sEnvs(ctx.env),\n image: `ghcr.io/no-trade-no-life/${COMPONENT_NAME}:${ctx.version ?? envCtx.version}`,\n imagePullPolicy: 'IfNotPresent',\n name: COMPONENT_NAME,\n resources: {\n limits: {\n cpu: ctx.cpu?.max ?? '500m',\n memory: ctx.memory?.max ?? '512Mi',\n },\n requests: {\n cpu: ctx.cpu?.min ?? '250m',\n memory: ctx.memory?.min ?? '256Mi',\n },\n },\n },\n ],\n hostname: COMPONENT_NAME,\n imagePullSecrets: [\n {\n name: 'pull-secret',\n },\n ],\n },\n },\n },\n },\n };\n },\n });\n};\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/lib/index.js ADDED
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const data_series_1 = require("@yuants/data-series");
7
+ const protocol_1 = require("@yuants/protocol");
8
+ const utils_1 = require("@yuants/utils");
9
+ const rxjs_1 = require("rxjs");
10
+ //@ts-ignore
11
+ const tradingview_1 = __importDefault(require("@mathieuc/tradingview"));
12
+ const terminal = protocol_1.Terminal.fromNodeEnv();
13
+ const DURATION_TO_TRADINGVIEW_PERIOD = {
14
+ PT1M: '1',
15
+ PT3M: '3',
16
+ PT5M: '5',
17
+ PT15M: '15',
18
+ PT30M: '30',
19
+ PT45M: '45',
20
+ PT1H: '60',
21
+ PT2H: '120',
22
+ PT3H: '180',
23
+ PT4H: '240',
24
+ P1D: '1D',
25
+ P1W: '1W',
26
+ P1M: '1M',
27
+ P3M: '3M',
28
+ P6M: '6M',
29
+ P1Y: '12M',
30
+ };
31
+ (0, data_series_1.createSeriesProvider)(terminal, {
32
+ tableName: 'ohlc',
33
+ series_id_prefix_parts: ['TradingView'],
34
+ reversed: false,
35
+ serviceOptions: { concurrent: +(process.env.CONCURRENCY || 2) },
36
+ queryFn: async ({ series_id, started_at, ended_at }) => {
37
+ const [datasource_id, product_id, duration] = (0, utils_1.decodePath)(series_id);
38
+ const offset = (0, utils_1.convertDurationToOffset)(duration);
39
+ if (!offset)
40
+ throw new Error(`Unsupported duration: ${duration}`);
41
+ const timeframe = DURATION_TO_TRADINGVIEW_PERIOD[duration];
42
+ if (!timeframe)
43
+ throw new Error(`Unsupported timeframe: ${duration}`);
44
+ const range = Math.ceil((ended_at - started_at) / offset);
45
+ if (range <= 0) {
46
+ throw `range=${range} is invalid`;
47
+ }
48
+ console.info((0, utils_1.formatTime)(Date.now()), 'queryChartRequest', JSON.stringify({ series_id, product_id, duration, range }));
49
+ const data = await (0, rxjs_1.firstValueFrom)(new rxjs_1.Observable((subscriber) => {
50
+ const client = new tradingview_1.default.Client();
51
+ const chart = new client.Session.Chart();
52
+ chart.setMarket(product_id, {
53
+ timeframe,
54
+ range,
55
+ to: ended_at,
56
+ });
57
+ chart.onError((e) => {
58
+ subscriber.error(e);
59
+ });
60
+ chart.onUpdate(() => {
61
+ const rawPeriods = chart.periods;
62
+ if (rawPeriods.length !== 0) {
63
+ const periods = rawPeriods.map((v) => ({
64
+ series_id,
65
+ created_at: (0, utils_1.formatTime)(v.time * 1000),
66
+ datasource_id,
67
+ product_id,
68
+ duration,
69
+ closed_at: (0, utils_1.formatTime)(v.time * 1000 + offset),
70
+ open: `${v.open}`,
71
+ high: `${v.max}`,
72
+ low: `${v.min}`,
73
+ close: `${v.close}`,
74
+ volume: `${v.volume}`,
75
+ open_interest: '0',
76
+ }));
77
+ subscriber.next(periods);
78
+ subscriber.complete();
79
+ }
80
+ });
81
+ return () => {
82
+ client.end();
83
+ };
84
+ }));
85
+ console.info((0, utils_1.formatTime)(Date.now()), 'queryChartResponse', JSON.stringify({
86
+ series_id,
87
+ product_id,
88
+ duration,
89
+ data_length: data.length,
90
+ }));
91
+ return data;
92
+ },
93
+ });
94
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { Terminal } from '@yuants/protocol';\nimport { convertDurationToOffset, decodePath, formatTime } from '@yuants/utils';\nimport { Observable, firstValueFrom } from 'rxjs';\n//@ts-ignore\nimport TradingView from '@mathieuc/tradingview';\n\nconst terminal = Terminal.fromNodeEnv();\n\nconst DURATION_TO_TRADINGVIEW_PERIOD: Record<string, string> = {\n PT1M: '1',\n PT3M: '3',\n PT5M: '5',\n PT15M: '15',\n PT30M: '30',\n PT45M: '45',\n PT1H: '60',\n PT2H: '120',\n PT3H: '180',\n PT4H: '240',\n P1D: '1D',\n P1W: '1W',\n P1M: '1M',\n P3M: '3M',\n P6M: '6M',\n P1Y: '12M',\n};\n\ncreateSeriesProvider(terminal, {\n tableName: 'ohlc',\n series_id_prefix_parts: ['TradingView'],\n reversed: false,\n serviceOptions: { concurrent: +(process.env.CONCURRENCY || 2) },\n queryFn: async ({ series_id, started_at, ended_at }) => {\n const [datasource_id, product_id, duration] = decodePath(series_id);\n const offset = convertDurationToOffset(duration);\n if (!offset) throw new Error(`Unsupported duration: ${duration}`);\n\n const timeframe = DURATION_TO_TRADINGVIEW_PERIOD[duration];\n if (!timeframe) throw new Error(`Unsupported timeframe: ${duration}`);\n\n const range = Math.ceil((ended_at - started_at) / offset);\n if (range <= 0) {\n throw `range=${range} is invalid`;\n }\n\n console.info(\n formatTime(Date.now()),\n 'queryChartRequest',\n JSON.stringify({ series_id, product_id, duration, range }),\n );\n\n const data = await firstValueFrom(\n new Observable<IOHLC[]>((subscriber) => {\n const client = new TradingView.Client();\n const chart = new client.Session.Chart();\n chart.setMarket(product_id, {\n timeframe,\n range,\n to: ended_at,\n });\n chart.onError((e: any) => {\n subscriber.error(e);\n });\n chart.onUpdate(() => {\n const rawPeriods: any[] = chart.periods;\n if (rawPeriods.length !== 0) {\n const periods = rawPeriods.map(\n (v): IOHLC => ({\n series_id,\n created_at: formatTime(v.time * 1000),\n datasource_id,\n product_id,\n duration,\n closed_at: formatTime(v.time * 1000 + offset),\n open: `${v.open}`,\n high: `${v.max}`,\n low: `${v.min}`,\n close: `${v.close}`,\n volume: `${v.volume}`,\n open_interest: '0',\n }),\n );\n subscriber.next(periods);\n subscriber.complete();\n }\n });\n return () => {\n client.end();\n };\n }),\n );\n\n console.info(\n formatTime(Date.now()),\n 'queryChartResponse',\n JSON.stringify({\n series_id,\n product_id,\n duration,\n data_length: data.length,\n }),\n );\n\n return data;\n },\n});\n"]}
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@yuants/vendor-trading-view",
3
- "version": "0.1.43",
3
+ "version": "0.2.1",
4
+ "bin": "lib/cli.js",
4
5
  "files": [
5
- "dist/extension.bundle.js"
6
+ "dist",
7
+ "lib",
8
+ "temp"
6
9
  ],
7
10
  "dependencies": {
8
11
  "@yuants/protocol": "0.37.2",
package/temp/image-tag ADDED
@@ -0,0 +1 @@
1
+ sha-d874a227bb05de1a2b679ef0cd689955dcfb72dd
@@ -0,0 +1,24 @@
1
+ {
2
+ "apps/vendor-trading-view/CHANGELOG.json": "bc27af3c4787822b8a8235cebe55d5cf8b1d9f48",
3
+ "apps/vendor-trading-view/CHANGELOG.md": "b5d42e1f9f5525b3fa41f1ce3725a879a71a0652",
4
+ "apps/vendor-trading-view/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
5
+ "apps/vendor-trading-view/build/Dockerfile": "7816c8d8a127707ee40487326bbde4bcfbb6280d",
6
+ "apps/vendor-trading-view/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
7
+ "apps/vendor-trading-view/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
8
+ "apps/vendor-trading-view/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
9
+ "apps/vendor-trading-view/etc/vendor-trading-view.api.md": "341d99a0258ce3dff77a871b518a458d33bb3df5",
10
+ "apps/vendor-trading-view/package.json": "c46a0ac5204eced8d772d369cb97b36b82e4eebd",
11
+ "apps/vendor-trading-view/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
12
+ "apps/vendor-trading-view/src/extension.ts": "452b7d7f0ee1b60de27648ae107f10cd683b2c48",
13
+ "apps/vendor-trading-view/src/index.ts": "be3c727ebe6e6bfad920f66d3d75b39a91e1a755",
14
+ "apps/vendor-trading-view/tsconfig.json": "c96157f0fbf3503af6f84e03a0df4ac624a82d47",
15
+ "apps/vendor-trading-view/.rush/temp/shrinkwrap-deps.json": "c7628aefb2275d409bfbd57b3355bd5f24683160",
16
+ "libraries/protocol/temp/package-deps.json": "d326f24867d9ae3fef16ff84ba537eabb7c8adf0",
17
+ "libraries/data-series/temp/package-deps.json": "3ba9330800ae3952ed7ba430526596a24d1e8eb7",
18
+ "libraries/sql/temp/package-deps.json": "1cb2248873d01ed732e8473f7b242a41f987fdd7",
19
+ "libraries/data-product/temp/package-deps.json": "634e636d948295079b02dbeffb84f6d52872fda8",
20
+ "libraries/utils/temp/package-deps.json": "c747617da1c0a40843603c62a7477da641ff0aef",
21
+ "libraries/data-ohlc/temp/package-deps.json": "f05db3bced2139edafc9a3d2c647d0987f974ce7",
22
+ "libraries/extension/temp/package-deps.json": "96816518ae9dc050cafe0b8fbce95cbb59d06ee6",
23
+ "tools/toolkit/temp/package-deps.json": "eb0447c467da3a90db0913ed01e42ec0de840234"
24
+ }
@@ -0,0 +1,177 @@
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/vendor-trading-view!",
165
+ "docComment": "",
166
+ "name": "@yuants/vendor-trading-view",
167
+ "preserveMemberOrder": false,
168
+ "members": [
169
+ {
170
+ "kind": "EntryPoint",
171
+ "canonicalReference": "@yuants/vendor-trading-view!",
172
+ "name": "",
173
+ "preserveMemberOrder": false,
174
+ "members": []
175
+ }
176
+ ]
177
+ }
@@ -0,0 +1,9 @@
1
+ ## API Report File for "@yuants/vendor-trading-view"
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
+ ```