@yuants/exchange 0.8.16 → 0.8.17
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/trade_history.js +32 -3
- package/dist/trade_history.js.map +1 -1
- package/lib/trade_history.d.ts.map +1 -1
- package/lib/trade_history.js +32 -3
- package/lib/trade_history.js.map +1 -1
- package/package.json +6 -6
- package/temp/build/typescript/ts_ji-pb6h_.json +1 -1
- package/temp/package-deps.json +5 -5
- package/temp/test/jest/haste-map-f50e7cc8db739b6ac2b07d506eb6fdee-b0f299de6a65bcc22988084da157f170-c4011bd9f6a16ae7503ec572fe00f1e3 +0 -0
- package/temp/test/jest/perf-cache-f50e7cc8db739b6ac2b07d506eb6fdee-da39a3ee5e6b4b0d3255bfef95601890 +1 -1
package/dist/trade_history.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { encodeTradeHistorySeriesId } from '@yuants/data-trade';
|
|
1
2
|
import { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';
|
|
3
|
+
import { formatTime } from '@yuants/utils';
|
|
2
4
|
const computeInterestRatePageRange = (items) => {
|
|
3
5
|
if (items.length === 0)
|
|
4
6
|
return undefined;
|
|
@@ -30,6 +32,7 @@ const TRADE_HISTORY_INSERT_COLUMNS = [
|
|
|
30
32
|
'fee_currency',
|
|
31
33
|
'pnl',
|
|
32
34
|
'created_at',
|
|
35
|
+
'origin',
|
|
33
36
|
];
|
|
34
37
|
/**
|
|
35
38
|
* @public
|
|
@@ -58,13 +61,13 @@ export const provideTradeHistoryService = (terminal, metadata, fetchPage, servic
|
|
|
58
61
|
const range = computeInterestRatePageRange(tradeHistory);
|
|
59
62
|
// Atomic write: data rows + series_data_range in the same statement.
|
|
60
63
|
if (tradeHistory.length > 0 && range) {
|
|
61
|
-
const
|
|
64
|
+
const writeTradeHistory = `${buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {
|
|
62
65
|
columns: TRADE_HISTORY_INSERT_COLUMNS,
|
|
63
66
|
conflictKeys: ['id', 'account_id'],
|
|
64
67
|
})} RETURNING 1`;
|
|
65
68
|
const writeRange = `${buildInsertManyIntoTableSQL([
|
|
66
69
|
{
|
|
67
|
-
series_id: msg.req.account_id,
|
|
70
|
+
series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),
|
|
68
71
|
table_name: 'trade_history',
|
|
69
72
|
start_time: range.start_time,
|
|
70
73
|
end_time: range.end_time,
|
|
@@ -76,7 +79,7 @@ export const provideTradeHistoryService = (terminal, metadata, fetchPage, servic
|
|
|
76
79
|
await requestSQL(terminal, `
|
|
77
80
|
WITH
|
|
78
81
|
write_trade_history AS (
|
|
79
|
-
${
|
|
82
|
+
${writeTradeHistory}
|
|
80
83
|
),
|
|
81
84
|
write_range AS (
|
|
82
85
|
${writeRange}
|
|
@@ -90,6 +93,32 @@ export const provideTradeHistoryService = (terminal, metadata, fetchPage, servic
|
|
|
90
93
|
conflictKeys: ['id', 'account_id'],
|
|
91
94
|
}));
|
|
92
95
|
}
|
|
96
|
+
else {
|
|
97
|
+
if ((metadata.type === 'HTX' ||
|
|
98
|
+
metadata.type === 'BITGET' ||
|
|
99
|
+
metadata.type === 'ASTER' ||
|
|
100
|
+
metadata.type === 'BINANCE') &&
|
|
101
|
+
tradeHistory.length === 0) {
|
|
102
|
+
if (msg.req.time >= Date.now() - 3600000 * 24 * 88 || msg.req.time === 0) {
|
|
103
|
+
msg.req.time = Math.max(msg.req.time, Date.now() - 3600000 * 24 * 88);
|
|
104
|
+
await requestSQL(terminal, buildInsertManyIntoTableSQL([
|
|
105
|
+
{
|
|
106
|
+
series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),
|
|
107
|
+
table_name: 'trade_history',
|
|
108
|
+
start_time: metadata.direction === 'backward'
|
|
109
|
+
? formatTime(msg.req.time - 48 * 3600000)
|
|
110
|
+
: formatTime(msg.req.time),
|
|
111
|
+
end_time: metadata.direction === 'backward'
|
|
112
|
+
? formatTime(msg.req.time)
|
|
113
|
+
: formatTime(msg.req.time + 48 * 3600000),
|
|
114
|
+
},
|
|
115
|
+
], 'series_data_range', {
|
|
116
|
+
columns: ['series_id', 'table_name', 'start_time', 'end_time'],
|
|
117
|
+
ignoreConflict: true,
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
93
122
|
return {
|
|
94
123
|
res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },
|
|
95
124
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trade_history.js","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"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","sourcesContent":["import { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { ITradeHistory } from '@yuants/data-trade';\nimport { ISeriesIngestResult } from './types';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\ninterface IIngestInterestLedgerRequest {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n trade_type: string;\n}\n\nconst computeInterestRatePageRange = (\n items: ITradeHistory[],\n): { start_time: string; end_time: string } | undefined => {\n if (items.length === 0) return undefined;\n\n let start = items[0];\n let startMs = Date.parse(start.created_at);\n let end = items[0];\n let endMs = Date.parse(end.created_at);\n\n for (const item of items) {\n const createdAtMs = Date.parse(item.created_at);\n if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {\n start = item;\n startMs = createdAtMs;\n }\n if (!isNaN(createdAtMs) && (isNaN(endMs) || createdAtMs > endMs)) {\n end = item;\n endMs = createdAtMs;\n }\n }\n\n return { start_time: start.created_at, end_time: end.created_at };\n};\n\nconst TRADE_HISTORY_INSERT_COLUMNS: Array<keyof ITradeHistory> = [\n 'id',\n 'product_id',\n 'account_id',\n 'direction',\n 'size',\n 'price',\n 'fee',\n 'fee_currency',\n 'pnl',\n 'created_at',\n];\n\n/**\n * @public\n */\nexport const provideTradeHistoryService = (\n terminal: Terminal,\n metadata: { direction: string; type: string; trade_type: string[] },\n fetchPage: (request: IIngestInterestLedgerRequest) => Promise<ITradeHistory[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestTradeHistory',\n {\n type: 'object',\n required: ['account_id', 'direction', 'time', 'credential', 'trade_type'],\n properties: {\n account_id: { type: 'string', pattern: `^${metadata.type}` },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n trade_type: { type: 'string', enum: metadata.trade_type },\n credential: {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: metadata.type },\n payload: { type: 'object' },\n },\n },\n },\n },\n async (msg) => {\n try {\n const tradeHistory = await fetchPage({ ...msg.req });\n const range = computeInterestRatePageRange(tradeHistory);\n // Atomic write: data rows + series_data_range in the same statement.\n if (tradeHistory.length > 0 && range) {\n const writeInterestRate = `${buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n })} RETURNING 1`;\n\n const writeRange = `${buildInsertManyIntoTableSQL(\n [\n {\n series_id: msg.req.account_id,\n table_name: 'trade_history',\n start_time: range.start_time,\n end_time: range.end_time,\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n )} RETURNING 1`;\n\n await requestSQL(\n terminal,\n `\n WITH\n write_trade_history AS (\n ${writeInterestRate}\n ),\n write_range AS (\n ${writeRange}\n )\n SELECT 1 as ok;\n `,\n );\n } else if (tradeHistory.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n }),\n );\n }\n\n return {\n res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n return { res: { code: 1, message } };\n }\n },\n serviceOptions,\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"trade_history.js","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"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","sourcesContent":["import { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { ITradeHistory, encodeTradeHistorySeriesId } from '@yuants/data-trade';\nimport { ISeriesIngestResult } from './types';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\ninterface IIngestInterestLedgerRequest {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n trade_type: string;\n}\n\nconst computeInterestRatePageRange = (\n items: ITradeHistory[],\n): { start_time: string; end_time: string } | undefined => {\n if (items.length === 0) return undefined;\n\n let start = items[0];\n let startMs = Date.parse(start.created_at);\n let end = items[0];\n let endMs = Date.parse(end.created_at);\n\n for (const item of items) {\n const createdAtMs = Date.parse(item.created_at);\n if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {\n start = item;\n startMs = createdAtMs;\n }\n if (!isNaN(createdAtMs) && (isNaN(endMs) || createdAtMs > endMs)) {\n end = item;\n endMs = createdAtMs;\n }\n }\n\n return { start_time: start.created_at, end_time: end.created_at };\n};\n\nconst TRADE_HISTORY_INSERT_COLUMNS: Array<keyof ITradeHistory> = [\n 'id',\n 'product_id',\n 'account_id',\n 'direction',\n 'size',\n 'price',\n 'fee',\n 'fee_currency',\n 'pnl',\n 'created_at',\n 'origin',\n];\n\n/**\n * @public\n */\nexport const provideTradeHistoryService = (\n terminal: Terminal,\n metadata: { direction: string; type: string; trade_type: string[] },\n fetchPage: (request: IIngestInterestLedgerRequest) => Promise<ITradeHistory[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestTradeHistory',\n {\n type: 'object',\n required: ['account_id', 'direction', 'time', 'credential', 'trade_type'],\n properties: {\n account_id: { type: 'string', pattern: `^${metadata.type}` },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n trade_type: { type: 'string', enum: metadata.trade_type },\n credential: {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: metadata.type },\n payload: { type: 'object' },\n },\n },\n },\n },\n async (msg) => {\n try {\n const tradeHistory = await fetchPage({ ...msg.req });\n const range = computeInterestRatePageRange(tradeHistory);\n // Atomic write: data rows + series_data_range in the same statement.\n if (tradeHistory.length > 0 && range) {\n const writeTradeHistory = `${buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n })} RETURNING 1`;\n\n const writeRange = `${buildInsertManyIntoTableSQL(\n [\n {\n series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),\n table_name: 'trade_history',\n start_time: range.start_time,\n end_time: range.end_time,\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n )} RETURNING 1`;\n\n await requestSQL(\n terminal,\n `\n WITH\n write_trade_history AS (\n ${writeTradeHistory}\n ),\n write_range AS (\n ${writeRange}\n )\n SELECT 1 as ok;\n `,\n );\n } else if (tradeHistory.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n }),\n );\n } else {\n if (\n (metadata.type === 'HTX' ||\n metadata.type === 'BITGET' ||\n metadata.type === 'ASTER' ||\n metadata.type === 'BINANCE') &&\n tradeHistory.length === 0\n ) {\n if (msg.req.time >= Date.now() - 3600_000 * 24 * 88 || msg.req.time === 0) {\n msg.req.time = Math.max(msg.req.time, Date.now() - 3600_000 * 24 * 88);\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(\n [\n {\n series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),\n table_name: 'trade_history',\n start_time:\n metadata.direction === 'backward'\n ? formatTime(msg.req.time - 48 * 3600_000)\n : formatTime(msg.req.time),\n end_time:\n metadata.direction === 'backward'\n ? formatTime(msg.req.time)\n : formatTime(msg.req.time + 48 * 3600_000),\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n ),\n );\n }\n }\n }\n\n return {\n res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n return { res: { code: 1, message } };\n }\n },\n serviceOptions,\n );\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trade_history.d.ts","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"trade_history.d.ts","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAA8B,MAAM,oBAAoB,CAAC;AAK/E,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd;AAED,UAAU,4BAA4B;IACpC,UAAU,EAAE,mBAAmB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAyCD;;GAEG;AACH,eAAO,MAAM,0BAA0B,GACrC,UAAU,QAAQ,EAClB,UAAU;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,EACnE,WAAW,CAAC,OAAO,EAAE,4BAA4B,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,EAC9E,iBAAiB,eAAe;;CAsHjC,CAAC"}
|
package/lib/trade_history.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.provideTradeHistoryService = void 0;
|
|
4
|
+
const data_trade_1 = require("@yuants/data-trade");
|
|
4
5
|
const sql_1 = require("@yuants/sql");
|
|
6
|
+
const utils_1 = require("@yuants/utils");
|
|
5
7
|
const computeInterestRatePageRange = (items) => {
|
|
6
8
|
if (items.length === 0)
|
|
7
9
|
return undefined;
|
|
@@ -33,6 +35,7 @@ const TRADE_HISTORY_INSERT_COLUMNS = [
|
|
|
33
35
|
'fee_currency',
|
|
34
36
|
'pnl',
|
|
35
37
|
'created_at',
|
|
38
|
+
'origin',
|
|
36
39
|
];
|
|
37
40
|
/**
|
|
38
41
|
* @public
|
|
@@ -61,13 +64,13 @@ const provideTradeHistoryService = (terminal, metadata, fetchPage, serviceOption
|
|
|
61
64
|
const range = computeInterestRatePageRange(tradeHistory);
|
|
62
65
|
// Atomic write: data rows + series_data_range in the same statement.
|
|
63
66
|
if (tradeHistory.length > 0 && range) {
|
|
64
|
-
const
|
|
67
|
+
const writeTradeHistory = `${(0, sql_1.buildInsertManyIntoTableSQL)(tradeHistory, 'trade_history', {
|
|
65
68
|
columns: TRADE_HISTORY_INSERT_COLUMNS,
|
|
66
69
|
conflictKeys: ['id', 'account_id'],
|
|
67
70
|
})} RETURNING 1`;
|
|
68
71
|
const writeRange = `${(0, sql_1.buildInsertManyIntoTableSQL)([
|
|
69
72
|
{
|
|
70
|
-
series_id: msg.req.account_id,
|
|
73
|
+
series_id: (0, data_trade_1.encodeTradeHistorySeriesId)(msg.req.account_id, msg.req.trade_type),
|
|
71
74
|
table_name: 'trade_history',
|
|
72
75
|
start_time: range.start_time,
|
|
73
76
|
end_time: range.end_time,
|
|
@@ -79,7 +82,7 @@ const provideTradeHistoryService = (terminal, metadata, fetchPage, serviceOption
|
|
|
79
82
|
await (0, sql_1.requestSQL)(terminal, `
|
|
80
83
|
WITH
|
|
81
84
|
write_trade_history AS (
|
|
82
|
-
${
|
|
85
|
+
${writeTradeHistory}
|
|
83
86
|
),
|
|
84
87
|
write_range AS (
|
|
85
88
|
${writeRange}
|
|
@@ -93,6 +96,32 @@ const provideTradeHistoryService = (terminal, metadata, fetchPage, serviceOption
|
|
|
93
96
|
conflictKeys: ['id', 'account_id'],
|
|
94
97
|
}));
|
|
95
98
|
}
|
|
99
|
+
else {
|
|
100
|
+
if ((metadata.type === 'HTX' ||
|
|
101
|
+
metadata.type === 'BITGET' ||
|
|
102
|
+
metadata.type === 'ASTER' ||
|
|
103
|
+
metadata.type === 'BINANCE') &&
|
|
104
|
+
tradeHistory.length === 0) {
|
|
105
|
+
if (msg.req.time >= Date.now() - 3600000 * 24 * 88 || msg.req.time === 0) {
|
|
106
|
+
msg.req.time = Math.max(msg.req.time, Date.now() - 3600000 * 24 * 88);
|
|
107
|
+
await (0, sql_1.requestSQL)(terminal, (0, sql_1.buildInsertManyIntoTableSQL)([
|
|
108
|
+
{
|
|
109
|
+
series_id: (0, data_trade_1.encodeTradeHistorySeriesId)(msg.req.account_id, msg.req.trade_type),
|
|
110
|
+
table_name: 'trade_history',
|
|
111
|
+
start_time: metadata.direction === 'backward'
|
|
112
|
+
? (0, utils_1.formatTime)(msg.req.time - 48 * 3600000)
|
|
113
|
+
: (0, utils_1.formatTime)(msg.req.time),
|
|
114
|
+
end_time: metadata.direction === 'backward'
|
|
115
|
+
? (0, utils_1.formatTime)(msg.req.time)
|
|
116
|
+
: (0, utils_1.formatTime)(msg.req.time + 48 * 3600000),
|
|
117
|
+
},
|
|
118
|
+
], 'series_data_range', {
|
|
119
|
+
columns: ['series_id', 'table_name', 'start_time', 'end_time'],
|
|
120
|
+
ignoreConflict: true,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
96
125
|
return {
|
|
97
126
|
res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },
|
|
98
127
|
};
|
package/lib/trade_history.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trade_history.js","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"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","sourcesContent":["import { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { ITradeHistory } from '@yuants/data-trade';\nimport { ISeriesIngestResult } from './types';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\ninterface IIngestInterestLedgerRequest {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n trade_type: string;\n}\n\nconst computeInterestRatePageRange = (\n items: ITradeHistory[],\n): { start_time: string; end_time: string } | undefined => {\n if (items.length === 0) return undefined;\n\n let start = items[0];\n let startMs = Date.parse(start.created_at);\n let end = items[0];\n let endMs = Date.parse(end.created_at);\n\n for (const item of items) {\n const createdAtMs = Date.parse(item.created_at);\n if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {\n start = item;\n startMs = createdAtMs;\n }\n if (!isNaN(createdAtMs) && (isNaN(endMs) || createdAtMs > endMs)) {\n end = item;\n endMs = createdAtMs;\n }\n }\n\n return { start_time: start.created_at, end_time: end.created_at };\n};\n\nconst TRADE_HISTORY_INSERT_COLUMNS: Array<keyof ITradeHistory> = [\n 'id',\n 'product_id',\n 'account_id',\n 'direction',\n 'size',\n 'price',\n 'fee',\n 'fee_currency',\n 'pnl',\n 'created_at',\n];\n\n/**\n * @public\n */\nexport const provideTradeHistoryService = (\n terminal: Terminal,\n metadata: { direction: string; type: string; trade_type: string[] },\n fetchPage: (request: IIngestInterestLedgerRequest) => Promise<ITradeHistory[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestTradeHistory',\n {\n type: 'object',\n required: ['account_id', 'direction', 'time', 'credential', 'trade_type'],\n properties: {\n account_id: { type: 'string', pattern: `^${metadata.type}` },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n trade_type: { type: 'string', enum: metadata.trade_type },\n credential: {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: metadata.type },\n payload: { type: 'object' },\n },\n },\n },\n },\n async (msg) => {\n try {\n const tradeHistory = await fetchPage({ ...msg.req });\n const range = computeInterestRatePageRange(tradeHistory);\n // Atomic write: data rows + series_data_range in the same statement.\n if (tradeHistory.length > 0 && range) {\n const writeInterestRate = `${buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n })} RETURNING 1`;\n\n const writeRange = `${buildInsertManyIntoTableSQL(\n [\n {\n series_id: msg.req.account_id,\n table_name: 'trade_history',\n start_time: range.start_time,\n end_time: range.end_time,\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n )} RETURNING 1`;\n\n await requestSQL(\n terminal,\n `\n WITH\n write_trade_history AS (\n ${writeInterestRate}\n ),\n write_range AS (\n ${writeRange}\n )\n SELECT 1 as ok;\n `,\n );\n } else if (tradeHistory.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n }),\n );\n }\n\n return {\n res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n return { res: { code: 1, message } };\n }\n },\n serviceOptions,\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"trade_history.js","sourceRoot":"","sources":["../src/trade_history.ts"],"names":[],"mappings":"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","sourcesContent":["import { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { ITradeHistory, encodeTradeHistorySeriesId } from '@yuants/data-trade';\nimport { ISeriesIngestResult } from './types';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\nimport { formatTime } from '@yuants/utils';\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\ninterface IIngestInterestLedgerRequest {\n credential: IExchangeCredential;\n account_id: string;\n time: number;\n trade_type: string;\n}\n\nconst computeInterestRatePageRange = (\n items: ITradeHistory[],\n): { start_time: string; end_time: string } | undefined => {\n if (items.length === 0) return undefined;\n\n let start = items[0];\n let startMs = Date.parse(start.created_at);\n let end = items[0];\n let endMs = Date.parse(end.created_at);\n\n for (const item of items) {\n const createdAtMs = Date.parse(item.created_at);\n if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {\n start = item;\n startMs = createdAtMs;\n }\n if (!isNaN(createdAtMs) && (isNaN(endMs) || createdAtMs > endMs)) {\n end = item;\n endMs = createdAtMs;\n }\n }\n\n return { start_time: start.created_at, end_time: end.created_at };\n};\n\nconst TRADE_HISTORY_INSERT_COLUMNS: Array<keyof ITradeHistory> = [\n 'id',\n 'product_id',\n 'account_id',\n 'direction',\n 'size',\n 'price',\n 'fee',\n 'fee_currency',\n 'pnl',\n 'created_at',\n 'origin',\n];\n\n/**\n * @public\n */\nexport const provideTradeHistoryService = (\n terminal: Terminal,\n metadata: { direction: string; type: string; trade_type: string[] },\n fetchPage: (request: IIngestInterestLedgerRequest) => Promise<ITradeHistory[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestInterestLedgerRequest, ISeriesIngestResult>(\n 'IngestTradeHistory',\n {\n type: 'object',\n required: ['account_id', 'direction', 'time', 'credential', 'trade_type'],\n properties: {\n account_id: { type: 'string', pattern: `^${metadata.type}` },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n trade_type: { type: 'string', enum: metadata.trade_type },\n credential: {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: metadata.type },\n payload: { type: 'object' },\n },\n },\n },\n },\n async (msg) => {\n try {\n const tradeHistory = await fetchPage({ ...msg.req });\n const range = computeInterestRatePageRange(tradeHistory);\n // Atomic write: data rows + series_data_range in the same statement.\n if (tradeHistory.length > 0 && range) {\n const writeTradeHistory = `${buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n })} RETURNING 1`;\n\n const writeRange = `${buildInsertManyIntoTableSQL(\n [\n {\n series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),\n table_name: 'trade_history',\n start_time: range.start_time,\n end_time: range.end_time,\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n )} RETURNING 1`;\n\n await requestSQL(\n terminal,\n `\n WITH\n write_trade_history AS (\n ${writeTradeHistory}\n ),\n write_range AS (\n ${writeRange}\n )\n SELECT 1 as ok;\n `,\n );\n } else if (tradeHistory.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(tradeHistory, 'trade_history', {\n columns: TRADE_HISTORY_INSERT_COLUMNS,\n conflictKeys: ['id', 'account_id'],\n }),\n );\n } else {\n if (\n (metadata.type === 'HTX' ||\n metadata.type === 'BITGET' ||\n metadata.type === 'ASTER' ||\n metadata.type === 'BINANCE') &&\n tradeHistory.length === 0\n ) {\n if (msg.req.time >= Date.now() - 3600_000 * 24 * 88 || msg.req.time === 0) {\n msg.req.time = Math.max(msg.req.time, Date.now() - 3600_000 * 24 * 88);\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(\n [\n {\n series_id: encodeTradeHistorySeriesId(msg.req.account_id, msg.req.trade_type),\n table_name: 'trade_history',\n start_time:\n metadata.direction === 'backward'\n ? formatTime(msg.req.time - 48 * 3600_000)\n : formatTime(msg.req.time),\n end_time:\n metadata.direction === 'backward'\n ? formatTime(msg.req.time)\n : formatTime(msg.req.time + 48 * 3600_000),\n },\n ],\n 'series_data_range',\n {\n columns: ['series_id', 'table_name', 'start_time', 'end_time'],\n ignoreConflict: true,\n },\n ),\n );\n }\n }\n }\n\n return {\n res: { code: 0, message: 'OK', data: { wrote_count: tradeHistory.length, range } },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n return { res: { code: 1, message } };\n }\n },\n serviceOptions,\n );\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuants/exchange",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.17",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"rxjs": "~7.5.6",
|
|
28
|
-
"@yuants/data-account": "0.11.8",
|
|
29
28
|
"@yuants/protocol": "0.54.1",
|
|
30
|
-
"@yuants/data-trade": "0.1.31",
|
|
31
|
-
"@yuants/data-product": "0.5.9",
|
|
32
29
|
"@yuants/data-order": "0.7.9",
|
|
30
|
+
"@yuants/data-trade": "0.1.32",
|
|
31
|
+
"@yuants/data-product": "0.5.9",
|
|
32
|
+
"@yuants/data-account": "0.11.8",
|
|
33
33
|
"@yuants/data-quote": "0.4.8",
|
|
34
|
-
"@yuants/data-interest-rate": "0.2.9",
|
|
35
34
|
"@yuants/data-ohlc": "0.6.4",
|
|
36
|
-
"@yuants/sql": "0.9.39",
|
|
37
35
|
"@yuants/cache": "0.3.12",
|
|
36
|
+
"@yuants/sql": "0.9.39",
|
|
37
|
+
"@yuants/data-interest-rate": "0.2.9",
|
|
38
38
|
"@yuants/utils": "0.19.4"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|