@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 +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/extension.js +105 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/vendor-trading-view.d.ts +1 -0
- package/lib/cli.d.ts +3 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +5 -0
- package/lib/cli.js.map +1 -0
- package/lib/extension.d.ts +4 -0
- package/lib/extension.d.ts.map +1 -0
- package/lib/extension.js +107 -0
- package/lib/extension.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +94 -0
- package/lib/index.js.map +1 -0
- package/package.json +5 -2
- package/temp/image-tag +1 -0
- package/temp/package-deps.json +24 -0
- package/temp/vendor-trading-view.api.json +177 -0
- package/temp/vendor-trading-view.api.md +9 -0
package/dist/cli.js
ADDED
package/dist/cli.js.map
ADDED
@@ -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
package/lib/cli.d.ts.map
ADDED
@@ -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
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 @@
|
|
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"}
|
package/lib/extension.js
ADDED
@@ -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":"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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/lib/index.d.ts
ADDED
@@ -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
|
package/lib/index.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AACA,qDAA2D;AAC3D,+CAA4C;AAC5C,yCAAgF;AAChF,+BAAkD;AAClD,YAAY;AACZ,wEAAgD;AAEhD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,MAAM,8BAA8B,GAA2B;IAC7D,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,IAAI,EAAE,KAAK;IACX,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,KAAK;CACX,CAAC;AAEF,IAAA,kCAAoB,EAAC,QAAQ,EAAE;IAC7B,SAAS,EAAE,MAAM;IACjB,sBAAsB,EAAE,CAAC,aAAa,CAAC;IACvC,QAAQ,EAAE,KAAK;IACf,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC,EAAE;IAC/D,OAAO,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrD,MAAM,CAAC,aAAa,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,IAAA,kBAAU,EAAC,SAAS,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,IAAA,+BAAuB,EAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QAElE,MAAM,SAAS,GAAG,8BAA8B,CAAC,QAAQ,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QAEtE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC,CAAC;QAC1D,IAAI,KAAK,IAAI,CAAC,EAAE;YACd,MAAM,SAAS,KAAK,aAAa,CAAC;SACnC;QAED,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,mBAAmB,EACnB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAC3D,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAc,EAC/B,IAAI,iBAAU,CAAU,CAAC,UAAU,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,IAAI,qBAAW,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACzC,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE;gBAC1B,SAAS;gBACT,KAAK;gBACL,EAAE,EAAE,QAAQ;aACb,CAAC,CAAC;YACH,KAAK,CAAC,OAAO,CAAC,CAAC,CAAM,EAAE,EAAE;gBACvB,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;gBAClB,MAAM,UAAU,GAAU,KAAK,CAAC,OAAO,CAAC;gBACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;oBAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAC5B,CAAC,CAAC,EAAS,EAAE,CAAC,CAAC;wBACb,SAAS;wBACT,UAAU,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;wBACrC,aAAa;wBACb,UAAU;wBACV,QAAQ;wBACR,SAAS,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;wBAC7C,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;wBACjB,IAAI,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE;wBAChB,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE;wBACf,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE;wBACnB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE;wBACrB,aAAa,EAAE,GAAG;qBACnB,CAAC,CACH,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACzB,UAAU,CAAC,QAAQ,EAAE,CAAC;iBACvB;YACH,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,EAAE;gBACV,MAAM,CAAC,GAAG,EAAE,CAAC;YACf,CAAC,CAAC;QACJ,CAAC,CAAC,CACH,CAAC;QAEF,OAAO,CAAC,IAAI,CACV,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EACtB,oBAAoB,EACpB,IAAI,CAAC,SAAS,CAAC;YACb,SAAS;YACT,UAAU;YACV,QAAQ;YACR,WAAW,EAAE,IAAI,CAAC,MAAM;SACzB,CAAC,CACH,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAC,CAAC","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
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
|
+
}
|