@yuants/vendor-coinex 0.1.36 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +119 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/extension.js +90 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/interest_rate.js +60 -0
- package/dist/interest_rate.js.map +1 -0
- package/dist/product.js +57 -0
- package/dist/product.js.map +1 -0
- package/dist/terminal.js +7 -0
- package/dist/terminal.js.map +1 -0
- package/dist/vendor-coinex.d.ts +1 -0
- package/lib/api.d.ts +142 -0
- package/lib/api.d.ts.map +1 -0
- package/lib/api.js +126 -0
- package/lib/api.js.map +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 +92 -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 +43 -0
- package/lib/index.js.map +1 -0
- package/lib/interest_rate.d.ts +2 -0
- package/lib/interest_rate.d.ts.map +1 -0
- package/lib/interest_rate.js +62 -0
- package/lib/interest_rate.js.map +1 -0
- package/lib/product.d.ts +14 -0
- package/lib/product.d.ts.map +1 -0
- package/lib/product.js +60 -0
- package/lib/product.js.map +1 -0
- package/lib/terminal.d.ts +3 -0
- package/lib/terminal.d.ts.map +1 -0
- package/lib/terminal.js +10 -0
- package/lib/terminal.js.map +1 -0
- package/lib/tsdoc-metadata.json +11 -0
- package/package.json +12 -7
- package/temp/image-tag +1 -0
- package/temp/package-deps.json +29 -0
- package/temp/vendor-coinex.api.json +177 -0
- package/temp/vendor-coinex.api.md +9 -0
package/lib/api.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
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
|
+
exports.client = exports.CoinExClient = void 0;
|
|
7
|
+
const utils_1 = require("@yuants/utils");
|
|
8
|
+
// @ts-ignore
|
|
9
|
+
const crypto_js_1 = __importDefault(require("crypto-js"));
|
|
10
|
+
const rxjs_1 = require("rxjs");
|
|
11
|
+
/**
|
|
12
|
+
* API: https://www.bitget.com/zh-CN/api-doc/common/intro
|
|
13
|
+
*/
|
|
14
|
+
class CoinExClient {
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.noAuth = true;
|
|
18
|
+
this.mapPathToRequestChannel = {};
|
|
19
|
+
/**
|
|
20
|
+
* 获取市场资金费率
|
|
21
|
+
*
|
|
22
|
+
* https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate
|
|
23
|
+
*/
|
|
24
|
+
this.getFuturesFundingRate = async (params) => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);
|
|
25
|
+
/**
|
|
26
|
+
* 获取市场资金费率历史记录
|
|
27
|
+
*
|
|
28
|
+
* https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history
|
|
29
|
+
*/
|
|
30
|
+
this.getFuturesFundingRateHistory = async (params) => this.requestWithFlowControl('GET', '/v2/futures/funding-rate-history', { period: 1000, limit: 400 }, params);
|
|
31
|
+
/**
|
|
32
|
+
* 获取市场状态
|
|
33
|
+
*
|
|
34
|
+
* https://docs.coinex.com/api/v2/zh/futures/market/http/list-market
|
|
35
|
+
*/
|
|
36
|
+
this.getFuturesMarket = async (params) => this.request('GET', '/v2/futures/market', params);
|
|
37
|
+
/**
|
|
38
|
+
* 获取市场行情
|
|
39
|
+
*
|
|
40
|
+
* https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker
|
|
41
|
+
*/
|
|
42
|
+
this.getFuturesTicker = async (params) => this.request('GET', '/v2/futures/ticker', params);
|
|
43
|
+
if (config.auth.access_key && config.auth.secret_key) {
|
|
44
|
+
this.noAuth = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async request(method, path, params) {
|
|
48
|
+
const url = new URL('https://api.coinex.com');
|
|
49
|
+
url.pathname = path;
|
|
50
|
+
if (method === 'GET' && params !== undefined) {
|
|
51
|
+
const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));
|
|
52
|
+
for (const [k, v] of sortedParams) {
|
|
53
|
+
url.searchParams.set(k, '' + v);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (this.noAuth) {
|
|
57
|
+
console.info((0, utils_1.formatTime)(Date.now()), method, url.href);
|
|
58
|
+
const res = await fetch(url.href, { method });
|
|
59
|
+
return res.json();
|
|
60
|
+
}
|
|
61
|
+
const timestamp = '' + Date.now();
|
|
62
|
+
const secret_key = this.config.auth.secret_key;
|
|
63
|
+
const body = method === 'GET' ? '' : JSON.stringify(params);
|
|
64
|
+
const signData = method + url.pathname + url.search + body + timestamp;
|
|
65
|
+
const str = crypto_js_1.default.enc.Base64.stringify(crypto_js_1.default.HmacSHA256(signData, secret_key));
|
|
66
|
+
const headers = {
|
|
67
|
+
'Content-Type': 'application/json',
|
|
68
|
+
'X-COINEX-KEY': this.config.auth.access_key,
|
|
69
|
+
'X-COINEX-SIGN': str,
|
|
70
|
+
'X-COINEX-TIMESTAMP': timestamp,
|
|
71
|
+
};
|
|
72
|
+
console.info((0, utils_1.formatTime)(Date.now()), method, url.href, JSON.stringify(headers), body, signData);
|
|
73
|
+
const res = await fetch(url.href, {
|
|
74
|
+
method,
|
|
75
|
+
headers,
|
|
76
|
+
body: body || undefined,
|
|
77
|
+
});
|
|
78
|
+
return res.json();
|
|
79
|
+
}
|
|
80
|
+
setupChannel(path, period, limit) {
|
|
81
|
+
this.mapPathToRequestChannel[path] = {
|
|
82
|
+
requestQueue: [],
|
|
83
|
+
responseChannel: new rxjs_1.Subject(),
|
|
84
|
+
};
|
|
85
|
+
const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];
|
|
86
|
+
(0, rxjs_1.timer)(0, period)
|
|
87
|
+
.pipe((0, rxjs_1.filter)(() => requestQueue.length > 0), (0, rxjs_1.mergeMap)(() => requestQueue.splice(0, limit)), (0, rxjs_1.mergeMap)(async (request) => {
|
|
88
|
+
try {
|
|
89
|
+
const res = await this.request(request.method, request.path, request.params);
|
|
90
|
+
return { trace_id: request.trace_id, response: res };
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return { trace_id: request.trace_id, error };
|
|
94
|
+
}
|
|
95
|
+
}))
|
|
96
|
+
.subscribe(responseChannel);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @param method - GET, POST, PUT, DELETE
|
|
100
|
+
* @param path - api path
|
|
101
|
+
* @param flowControl - period in ms, limit in count
|
|
102
|
+
* @param params - request params/body
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
async requestWithFlowControl(method, path, flowControl = { period: 10, limit: Infinity }, params) {
|
|
106
|
+
const { period, limit } = flowControl;
|
|
107
|
+
if (!this.mapPathToRequestChannel[path]) {
|
|
108
|
+
this.setupChannel(path, period, limit);
|
|
109
|
+
}
|
|
110
|
+
const uuid = (0, utils_1.UUID)();
|
|
111
|
+
const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];
|
|
112
|
+
const res$ = responseChannel.pipe(
|
|
113
|
+
//
|
|
114
|
+
(0, rxjs_1.filter)((response) => response.trace_id === uuid), (0, rxjs_1.mergeMap)((response) => (response.error ? (0, rxjs_1.throwError)(() => response.error) : (0, rxjs_1.of)(response))), (0, rxjs_1.timeout)(30000), (0, rxjs_1.shareReplay)(1));
|
|
115
|
+
requestQueue.push({ trace_id: uuid, method, path, params });
|
|
116
|
+
return (await (0, rxjs_1.firstValueFrom)(res$)).response;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.CoinExClient = CoinExClient;
|
|
120
|
+
exports.client = new CoinExClient({
|
|
121
|
+
auth: {
|
|
122
|
+
access_key: process.env.ACCESS_KEY,
|
|
123
|
+
secret_key: process.env.SECRET_KEY,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAiD;AACjD,aAAa;AACb,0DAAiC;AACjC,+BAA8G;AAE9G;;GAEG;AACH,MAAa,YAAY;IAEvB,YACS,MAKN;QALM,WAAM,GAAN,MAAM,CAKZ;QAPH,WAAM,GAAG,IAAI,CAAC;QAmDd,4BAAuB,GAWnB,EAAE,CAAC;QAwDP;;;;WAIG;QACH,0BAAqB,GAAG,KAAK,EAAE,MAE9B,EAaE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,0BAA0B,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;QAE3G;;;;WAIG;QACH,iCAA4B,GAAG,KAAK,EAAE,MAMrC,EAYE,EAAE,CACH,IAAI,CAAC,sBAAsB,CACzB,KAAK,EACL,kCAAkC,EAClC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAC5B,MAAM,CACP,CAAC;QAEJ;;;;WAIG;QACH,qBAAgB,GAAG,KAAK,EAAE,MAEzB,EAgBE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAExD;;;;WAIG;QACH,qBAAgB,GAAG,KAAK,EAAE,MAEzB,EAkBE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;QApNtD,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE;YACpD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;SACrB;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,IAAY,EAAE,MAAY;QACtD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,wBAAwB,CAAC,CAAC;QAC9C,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;QACpB,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,SAAS,EAAE;YAC5C,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,YAAY,EAAE;gBACjC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;aACjC;SACF;QACD,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,OAAO,CAAC,IAAI,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;SACnB;QACD,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;QACvE,MAAM,GAAG,GAAG,mBAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;QAErF,MAAM,OAAO,GAAG;YACd,cAAc,EAAE,kBAAkB;YAClC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAW;YAC5C,eAAe,EAAE,GAAG;YACpB,oBAAoB,EAAE,SAAS;SAChC,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,IAAA,kBAAU,EAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAChG,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;YAChC,MAAM;YACN,OAAO;YACP,IAAI,EAAE,IAAI,IAAI,SAAS;SACxB,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAeD,YAAY,CAAC,IAAY,EAAE,MAAc,EAAE,KAAa;QACtD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG;YACnC,YAAY,EAAE,EAAE;YAChB,eAAe,EAAE,IAAI,cAAO,EAAE;SAC/B,CAAC;QAEF,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAC7E,IAAA,YAAK,EAAC,CAAC,EAAE,MAAM,CAAC;aACb,IAAI,CACH,IAAA,aAAM,EAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,EACrC,IAAA,eAAQ,EAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAC7C,IAAA,eAAQ,EAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YACzB,IAAI;gBACF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC7E,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;aACtD;YAAC,OAAO,KAAK,EAAE;gBACd,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;aAC9C;QACH,CAAC,CAAC,CACH;aACA,SAAS,CAAC,eAAe,CAAC,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,sBAAsB,CAC1B,MAAc,EACd,IAAY,EACZ,cAAiD,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAChF,MAAY;QAEZ,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE;YACvC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;SACxC;QACD,MAAM,IAAI,GAAG,IAAA,YAAI,GAAE,CAAC;QAEpB,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAC7E,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI;QAC/B,EAAE;QACF,IAAA,aAAM,EAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,EAChD,IAAA,eAAQ,EAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,iBAAU,EAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAA,SAAE,EAAC,QAAQ,CAAC,CAAC,CAAC,EAC1F,IAAA,cAAO,EAAC,KAAM,CAAC,EACf,IAAA,kBAAW,EAAC,CAAC,CAAC,CACf,CAAC;QACF,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5D,OAAO,CAAC,MAAM,IAAA,qBAAc,EAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC/C,CAAC;CA0GF;AA/ND,oCA+NC;AAEY,QAAA,MAAM,GAAG,IAAI,YAAY,CAAC;IACrC,IAAI,EAAE;QACJ,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;QACnC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;KACpC;CACF,CAAC,CAAC","sourcesContent":["import { UUID, formatTime } from '@yuants/utils';\n// @ts-ignore\nimport CryptoJS from 'crypto-js';\nimport { Subject, filter, firstValueFrom, mergeMap, of, shareReplay, throwError, timeout, timer } from 'rxjs';\n\n/**\n * API: https://www.bitget.com/zh-CN/api-doc/common/intro\n */\nexport class CoinExClient {\n noAuth = true;\n constructor(\n public config: {\n auth: {\n access_key: string;\n secret_key: string;\n };\n },\n ) {\n if (config.auth.access_key && config.auth.secret_key) {\n this.noAuth = false;\n }\n }\n\n async request(method: string, path: string, params?: any) {\n const url = new URL('https://api.coinex.com');\n url.pathname = path;\n if (method === 'GET' && params !== undefined) {\n const sortedParams = Object.entries(params).sort(([a], [b]) => a.localeCompare(b));\n for (const [k, v] of sortedParams) {\n url.searchParams.set(k, '' + v);\n }\n }\n if (this.noAuth) {\n console.info(formatTime(Date.now()), method, url.href);\n const res = await fetch(url.href, { method });\n return res.json();\n }\n const timestamp = '' + Date.now();\n const secret_key = this.config.auth.secret_key;\n const body = method === 'GET' ? '' : JSON.stringify(params);\n const signData = method + url.pathname + url.search + body + timestamp;\n const str = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(signData, secret_key));\n\n const headers = {\n 'Content-Type': 'application/json',\n 'X-COINEX-KEY': this.config.auth.access_key!,\n 'X-COINEX-SIGN': str,\n 'X-COINEX-TIMESTAMP': timestamp,\n };\n\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(headers), body, signData);\n const res = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n });\n\n return res.json();\n }\n\n mapPathToRequestChannel: Record<\n string,\n {\n requestQueue: Array<{\n trace_id: string;\n method: string;\n path: string;\n params?: any;\n }>;\n responseChannel: Subject<{ trace_id: string; response?: any; error?: Error }>;\n }\n > = {};\n\n setupChannel(path: string, period: number, limit: number) {\n this.mapPathToRequestChannel[path] = {\n requestQueue: [],\n responseChannel: new Subject(),\n };\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n timer(0, period)\n .pipe(\n filter(() => requestQueue.length > 0),\n mergeMap(() => requestQueue.splice(0, limit)),\n mergeMap(async (request) => {\n try {\n const res = await this.request(request.method, request.path, request.params);\n return { trace_id: request.trace_id, response: res };\n } catch (error) {\n return { trace_id: request.trace_id, error };\n }\n }),\n )\n .subscribe(responseChannel);\n }\n\n /**\n * @param method - GET, POST, PUT, DELETE\n * @param path - api path\n * @param flowControl - period in ms, limit in count\n * @param params - request params/body\n * @returns\n */\n async requestWithFlowControl(\n method: string,\n path: string,\n flowControl: { period: number; limit: number } = { period: 10, limit: Infinity },\n params?: any,\n ) {\n const { period, limit } = flowControl;\n if (!this.mapPathToRequestChannel[path]) {\n this.setupChannel(path, period, limit);\n }\n const uuid = UUID();\n\n const { requestQueue, responseChannel } = this.mapPathToRequestChannel[path];\n const res$ = responseChannel.pipe(\n //\n filter((response) => response.trace_id === uuid),\n mergeMap((response) => (response.error ? throwError(() => response.error) : of(response))),\n timeout(30_000),\n shareReplay(1),\n );\n requestQueue.push({ trace_id: uuid, method, path, params });\n return (await firstValueFrom(res$)).response;\n }\n\n /**\n * 获取市场资金费率\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate\n */\n getFuturesFundingRate = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n mark_price: string;\n latest_funding_rate: string;\n next_funding_rate: string;\n max_funding_time: string;\n min_funding_time: string;\n latest_funding_time: number;\n next_funding_time: number;\n }[];\n }> => this.requestWithFlowControl('GET', '/v2/futures/funding-rate', { period: 1000, limit: 400 }, params);\n\n /**\n * 获取市场资金费率历史记录\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-funding-rate-history\n */\n getFuturesFundingRateHistory = async (params: {\n market: string;\n start_time?: number;\n end_time?: number;\n page?: number;\n limit?: number;\n }): Promise<{\n code: number;\n message: string;\n pagination: {\n has_next: boolean;\n };\n data: {\n market: string;\n funding_time: number;\n theoretical_funding_rate: string;\n actual_funding_rate: string;\n }[];\n }> =>\n this.requestWithFlowControl(\n 'GET',\n '/v2/futures/funding-rate-history',\n { period: 1000, limit: 400 },\n params,\n );\n\n /**\n * 获取市场状态\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market\n */\n getFuturesMarket = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n contract_type: string;\n maker_fee_rate: string;\n taker_fee_rate: string;\n min_amount: string;\n base_ccy: string;\n quote_ccy: string;\n base_ccy_precision: number;\n quote_ccy_precision: number;\n leverage: number[];\n open_interest_volume: string;\n }[];\n }> => this.request('GET', '/v2/futures/market', params);\n\n /**\n * 获取市场行情\n *\n * https://docs.coinex.com/api/v2/zh/futures/market/http/list-market-ticker\n */\n getFuturesTicker = async (params?: {\n market?: string;\n }): Promise<{\n code: number;\n message: string;\n data: {\n market: string;\n last: string;\n open: string;\n close: string;\n high: string;\n low: string;\n volume: string;\n value: string;\n volume_sell: string;\n volume_buy: string;\n index_price: string;\n mark_price: string;\n period: number;\n }[];\n }> => this.request('GET', '/v2/futures/ticker', params);\n}\n\nexport const client = new CoinExClient({\n auth: {\n access_key: process.env.ACCESS_KEY!,\n secret_key: process.env.SECRET_KEY!,\n },\n});\n"]}
|
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,wBAsFE"}
|
package/lib/extension.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const extension_1 = require("@yuants/extension");
|
|
4
|
+
exports.default = (context) => {
|
|
5
|
+
context.registerDeployProvider({
|
|
6
|
+
make_json_schema: () => ({
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
env: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
required: ['HOST_URL'],
|
|
12
|
+
properties: {
|
|
13
|
+
//
|
|
14
|
+
HOST_URL: { type: 'string' },
|
|
15
|
+
TERMINAL_ID: { type: 'string' },
|
|
16
|
+
ACCESS_KEY: { type: 'string' },
|
|
17
|
+
SECRET_KEY: { type: 'string' },
|
|
18
|
+
PASSPHRASE: { type: 'string' },
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
make_docker_compose_file: async (ctx, envCtx) => {
|
|
24
|
+
var _a;
|
|
25
|
+
return {
|
|
26
|
+
[`coinex-${ctx.env.ACCESS_KEY}`.replace(/\s/g, '')]: {
|
|
27
|
+
image: `ghcr.io/no-trade-no-life/vendor-coinex:${(_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version}`,
|
|
28
|
+
restart: 'always',
|
|
29
|
+
environment: (0, extension_1.makeDockerEnvs)(ctx.env),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
make_k8s_resource_objects: async (ctx, envCtx) => {
|
|
34
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
35
|
+
return {
|
|
36
|
+
deployment: {
|
|
37
|
+
apiVersion: 'apps/v1',
|
|
38
|
+
kind: 'Deployment',
|
|
39
|
+
metadata: {
|
|
40
|
+
labels: {
|
|
41
|
+
'y.ntnl.io/version': (_a = ctx.version) !== null && _a !== void 0 ? _a : envCtx.version,
|
|
42
|
+
'y.ntnl.io/manifest_key': ctx.key,
|
|
43
|
+
'y.ntnl.io/component': 'coinex',
|
|
44
|
+
},
|
|
45
|
+
name: `coinex-${ctx.key}`.replace(/\s/g, '').toLocaleLowerCase(),
|
|
46
|
+
namespace: 'yuan',
|
|
47
|
+
},
|
|
48
|
+
spec: {
|
|
49
|
+
replicas: 1,
|
|
50
|
+
selector: {
|
|
51
|
+
matchLabels: {
|
|
52
|
+
'y.ntnl.io/component': 'coinex',
|
|
53
|
+
'y.ntnl.io/manifest_key': ctx.key,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
template: {
|
|
57
|
+
metadata: {
|
|
58
|
+
labels: {
|
|
59
|
+
'y.ntnl.io/version': (_b = ctx.version) !== null && _b !== void 0 ? _b : envCtx.version,
|
|
60
|
+
'y.ntnl.io/manifest_key': ctx.key,
|
|
61
|
+
'y.ntnl.io/component': 'coinex',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
spec: {
|
|
65
|
+
containers: [
|
|
66
|
+
{
|
|
67
|
+
env: (0, extension_1.makeK8sEnvs)(ctx.env),
|
|
68
|
+
image: `ghcr.io/no-trade-no-life/vendor-coinex:${(_c = ctx.version) !== null && _c !== void 0 ? _c : envCtx.version}`,
|
|
69
|
+
imagePullPolicy: 'IfNotPresent',
|
|
70
|
+
name: 'coinex',
|
|
71
|
+
resources: {
|
|
72
|
+
limits: {
|
|
73
|
+
cpu: (_e = (_d = ctx.cpu) === null || _d === void 0 ? void 0 : _d.max) !== null && _e !== void 0 ? _e : '500m',
|
|
74
|
+
memory: (_g = (_f = ctx.memory) === null || _f === void 0 ? void 0 : _f.max) !== null && _g !== void 0 ? _g : '256Mi',
|
|
75
|
+
},
|
|
76
|
+
requests: {
|
|
77
|
+
cpu: (_j = (_h = ctx.cpu) === null || _h === void 0 ? void 0 : _h.min) !== null && _j !== void 0 ? _j : '100m',
|
|
78
|
+
memory: (_l = (_k = ctx.memory) === null || _k === void 0 ? void 0 : _k.min) !== null && _l !== void 0 ? _l : '128Mi',
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
hostname: 'coinex',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
//# 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 context.registerDeployProvider({\n make_json_schema: () => ({\n type: 'object',\n properties: {\n env: {\n type: 'object',\n required: ['HOST_URL'],\n properties: {\n //\n HOST_URL: { type: 'string' },\n TERMINAL_ID: { type: 'string' },\n ACCESS_KEY: { type: 'string' },\n SECRET_KEY: { type: 'string' },\n PASSPHRASE: { type: 'string' },\n },\n },\n },\n }),\n make_docker_compose_file: async (ctx, envCtx) => {\n return {\n [`coinex-${ctx.env!.ACCESS_KEY}`.replace(/\\s/g, '')]: {\n image: `ghcr.io/no-trade-no-life/vendor-coinex:${ctx.version ?? envCtx.version}`,\n restart: 'always',\n\n environment: makeDockerEnvs(ctx.env),\n },\n };\n },\n make_k8s_resource_objects: async (ctx, envCtx) => {\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/manifest_key': ctx.key,\n 'y.ntnl.io/component': 'coinex',\n },\n name: `coinex-${ctx.key}`.replace(/\\s/g, '').toLocaleLowerCase(),\n namespace: 'yuan',\n },\n spec: {\n replicas: 1,\n selector: {\n matchLabels: {\n 'y.ntnl.io/component': 'coinex',\n 'y.ntnl.io/manifest_key': ctx.key,\n },\n },\n template: {\n metadata: {\n labels: {\n 'y.ntnl.io/version': ctx.version ?? envCtx.version,\n 'y.ntnl.io/manifest_key': ctx.key,\n 'y.ntnl.io/component': 'coinex',\n },\n },\n spec: {\n containers: [\n {\n env: makeK8sEnvs(ctx.env),\n image: `ghcr.io/no-trade-no-life/vendor-coinex:${ctx.version ?? envCtx.version}`,\n imagePullPolicy: 'IfNotPresent',\n name: 'coinex',\n resources: {\n limits: {\n cpu: ctx.cpu?.max ?? '500m',\n memory: ctx.memory?.max ?? '256Mi',\n },\n requests: {\n cpu: ctx.cpu?.min ?? '100m',\n memory: ctx.memory?.min ?? '128Mi',\n },\n },\n },\n ],\n hostname: 'coinex',\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":"AAEA,OAAO,iBAAiB,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const rxjs_1 = require("rxjs");
|
|
4
|
+
const api_1 = require("./api");
|
|
5
|
+
require("./interest_rate");
|
|
6
|
+
const mapSymbolToFundingRate$ = (0, rxjs_1.defer)(() => api_1.client.getFuturesFundingRate()).pipe(
|
|
7
|
+
//
|
|
8
|
+
(0, rxjs_1.map)((v) => v.data), (0, rxjs_1.repeat)({ delay: 1000 }), (0, rxjs_1.retry)({ delay: 30000 }), (0, rxjs_1.mergeMap)((x) => (0, rxjs_1.from)(x).pipe((0, rxjs_1.map)((v) => [v.market, v]), (0, rxjs_1.toArray)(), (0, rxjs_1.map)((v) => new Map(v)))), (0, rxjs_1.shareReplay)(1));
|
|
9
|
+
const mapSymbolToTicker$ = (0, rxjs_1.defer)(() => api_1.client.getFuturesTicker()).pipe(
|
|
10
|
+
//
|
|
11
|
+
(0, rxjs_1.map)((v) => v.data), (0, rxjs_1.repeat)({ delay: 1000 }), (0, rxjs_1.retry)({ delay: 30000 }), (0, rxjs_1.mergeMap)((x) => (0, rxjs_1.from)(x).pipe((0, rxjs_1.map)((v) => [v.market, v]), (0, rxjs_1.toArray)(), (0, rxjs_1.map)((v) => new Map(v)))), (0, rxjs_1.shareReplay)(1));
|
|
12
|
+
// provideTicks(terminal, 'COINEX', (product_id) => {
|
|
13
|
+
// const [instType, instId] = decodePath(product_id);
|
|
14
|
+
// if (instType !== 'SWAP') return [];
|
|
15
|
+
// return combineLatest([mapSymbolToTicker$, mapSymbolToMarket$, mapSymbolToFundingRate$]).pipe(
|
|
16
|
+
// //
|
|
17
|
+
// map(([mapSymbolToTicker, mapSymbolToMarket, mapSymbolToFundingRate]): ITick => {
|
|
18
|
+
// const ticker = mapSymbolToTicker.get(instId);
|
|
19
|
+
// const market = mapSymbolToMarket.get(instId);
|
|
20
|
+
// const fundingRate = mapSymbolToFundingRate.get(instId);
|
|
21
|
+
// if (!ticker) {
|
|
22
|
+
// throw new Error(`ticker ${instId} not found`);
|
|
23
|
+
// }
|
|
24
|
+
// if (!market) {
|
|
25
|
+
// throw new Error(`market ${instId} not found`);
|
|
26
|
+
// }
|
|
27
|
+
// if (!fundingRate) {
|
|
28
|
+
// throw new Error(`fundingRate ${instId} not found`);
|
|
29
|
+
// }
|
|
30
|
+
// return {
|
|
31
|
+
// product_id,
|
|
32
|
+
// datasource_id: 'COINEX',
|
|
33
|
+
// updated_at: Date.now(),
|
|
34
|
+
// price: +ticker.last,
|
|
35
|
+
// interest_rate_for_long: -+fundingRate.latest_funding_rate,
|
|
36
|
+
// interest_rate_for_short: +fundingRate.latest_funding_rate,
|
|
37
|
+
// settlement_scheduled_at: +fundingRate.next_funding_time,
|
|
38
|
+
// open_interest: +market.open_interest_volume,
|
|
39
|
+
// };
|
|
40
|
+
// }),
|
|
41
|
+
// );
|
|
42
|
+
// });
|
|
43
|
+
//# 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":";;AAAA,+BAAuF;AACvF,+BAA+B;AAC/B,2BAAyB;AAEzB,MAAM,uBAAuB,GAAG,IAAA,YAAK,EAAC,GAAG,EAAE,CAAC,YAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,IAAI;AAC9E,EAAE;AACF,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAClB,IAAA,aAAM,EAAC,EAAE,KAAK,EAAE,IAAK,EAAE,CAAC,EACxB,IAAA,YAAK,EAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACxB,IAAA,eAAQ,EAAC,CAAC,CAAC,EAAE,EAAE,CACb,IAAA,WAAI,EAAC,CAAC,CAAC,CAAC,IAAI,CACV,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAU,CAAC,EAClC,IAAA,cAAO,GAAE,EACT,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CACvB,CACF,EACD,IAAA,kBAAW,EAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAA,YAAK,EAAC,GAAG,EAAE,CAAC,YAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,IAAI;AACpE,EAAE;AACF,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAClB,IAAA,aAAM,EAAC,EAAE,KAAK,EAAE,IAAK,EAAE,CAAC,EACxB,IAAA,YAAK,EAAC,EAAE,KAAK,EAAE,KAAM,EAAE,CAAC,EACxB,IAAA,eAAQ,EAAC,CAAC,CAAC,EAAE,EAAE,CACb,IAAA,WAAI,EAAC,CAAC,CAAC,CAAC,IAAI,CACV,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAU,CAAC,EAClC,IAAA,cAAO,GAAE,EACT,IAAA,UAAG,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CACvB,CACF,EACD,IAAA,kBAAW,EAAC,CAAC,CAAC,CACf,CAAC;AAEF,qDAAqD;AACrD,uDAAuD;AACvD,wCAAwC;AACxC,kGAAkG;AAClG,SAAS;AACT,uFAAuF;AACvF,sDAAsD;AACtD,sDAAsD;AACtD,gEAAgE;AAChE,uBAAuB;AACvB,yDAAyD;AACzD,UAAU;AACV,uBAAuB;AACvB,yDAAyD;AACzD,UAAU;AACV,4BAA4B;AAC5B,8DAA8D;AAC9D,UAAU;AACV,iBAAiB;AACjB,sBAAsB;AACtB,mCAAmC;AACnC,kCAAkC;AAClC,+BAA+B;AAC/B,qEAAqE;AACrE,qEAAqE;AACrE,mEAAmE;AACnE,uDAAuD;AACvD,WAAW;AACX,UAAU;AACV,OAAO;AACP,MAAM","sourcesContent":["import { defer, from, map, mergeMap, repeat, retry, shareReplay, toArray } from 'rxjs';\nimport { client } from './api';\nimport './interest_rate';\n\nconst mapSymbolToFundingRate$ = defer(() => client.getFuturesFundingRate()).pipe(\n //\n map((v) => v.data),\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n mergeMap((x) =>\n from(x).pipe(\n map((v) => [v.market, v] as const),\n toArray(),\n map((v) => new Map(v)),\n ),\n ),\n shareReplay(1),\n);\n\nconst mapSymbolToTicker$ = defer(() => client.getFuturesTicker()).pipe(\n //\n map((v) => v.data),\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n mergeMap((x) =>\n from(x).pipe(\n map((v) => [v.market, v] as const),\n toArray(),\n map((v) => new Map(v)),\n ),\n ),\n shareReplay(1),\n);\n\n// provideTicks(terminal, 'COINEX', (product_id) => {\n// const [instType, instId] = decodePath(product_id);\n// if (instType !== 'SWAP') return [];\n// return combineLatest([mapSymbolToTicker$, mapSymbolToMarket$, mapSymbolToFundingRate$]).pipe(\n// //\n// map(([mapSymbolToTicker, mapSymbolToMarket, mapSymbolToFundingRate]): ITick => {\n// const ticker = mapSymbolToTicker.get(instId);\n// const market = mapSymbolToMarket.get(instId);\n// const fundingRate = mapSymbolToFundingRate.get(instId);\n// if (!ticker) {\n// throw new Error(`ticker ${instId} not found`);\n// }\n// if (!market) {\n// throw new Error(`market ${instId} not found`);\n// }\n// if (!fundingRate) {\n// throw new Error(`fundingRate ${instId} not found`);\n// }\n// return {\n// product_id,\n// datasource_id: 'COINEX',\n// updated_at: Date.now(),\n// price: +ticker.last,\n// interest_rate_for_long: -+fundingRate.latest_funding_rate,\n// interest_rate_for_short: +fundingRate.latest_funding_rate,\n// settlement_scheduled_at: +fundingRate.next_funding_time,\n// open_interest: +market.open_interest_volume,\n// };\n// }),\n// );\n// });\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interest_rate.d.ts","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
3
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
4
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
5
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
6
|
+
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
7
|
+
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
|
8
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
9
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
10
|
+
function fulfill(value) { resume("next", value); }
|
|
11
|
+
function reject(value) { resume("throw", value); }
|
|
12
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const data_series_1 = require("@yuants/data-series");
|
|
16
|
+
const utils_1 = require("@yuants/utils");
|
|
17
|
+
const rxjs_1 = require("rxjs");
|
|
18
|
+
const api_1 = require("./api");
|
|
19
|
+
const terminal_1 = require("./terminal");
|
|
20
|
+
(0, data_series_1.createSeriesProvider)(terminal_1.terminal, {
|
|
21
|
+
tableName: 'interest_rate',
|
|
22
|
+
series_id_prefix_parts: ['coinex'],
|
|
23
|
+
reversed: true,
|
|
24
|
+
serviceOptions: { concurrent: 1 },
|
|
25
|
+
queryFn: function ({ series_id, started_at, ended_at }) {
|
|
26
|
+
return __asyncGenerator(this, arguments, function* () {
|
|
27
|
+
const [datasource_id, product_id] = (0, utils_1.decodePath)(series_id);
|
|
28
|
+
const [instType, instId] = (0, utils_1.decodePath)(product_id);
|
|
29
|
+
let current_page = 0;
|
|
30
|
+
while (true) {
|
|
31
|
+
const res = yield __await(api_1.client.getFuturesFundingRateHistory({
|
|
32
|
+
market: instId,
|
|
33
|
+
start_time: started_at,
|
|
34
|
+
end_time: ended_at,
|
|
35
|
+
page: current_page,
|
|
36
|
+
limit: 100,
|
|
37
|
+
}));
|
|
38
|
+
if (res.code !== 0) {
|
|
39
|
+
throw `API failed: ${res.code} ${res.message}`;
|
|
40
|
+
}
|
|
41
|
+
if (res.data.length === 0)
|
|
42
|
+
break;
|
|
43
|
+
yield yield __await(res.data.map((v) => ({
|
|
44
|
+
series_id,
|
|
45
|
+
datasource_id,
|
|
46
|
+
product_id,
|
|
47
|
+
created_at: (0, utils_1.formatTime)(+v.funding_time),
|
|
48
|
+
long_rate: `${-v.actual_funding_rate}`,
|
|
49
|
+
short_rate: `${v.actual_funding_rate}`,
|
|
50
|
+
settlement_price: '',
|
|
51
|
+
})));
|
|
52
|
+
if (!res.pagination.has_next)
|
|
53
|
+
break;
|
|
54
|
+
if (+res.data[res.data.length - 1].funding_time <= started_at)
|
|
55
|
+
break;
|
|
56
|
+
current_page++;
|
|
57
|
+
yield __await((0, rxjs_1.firstValueFrom)((0, rxjs_1.timer)(1000)));
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=interest_rate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,qDAA2D;AAC3D,yCAAuD;AACvD,+BAA6C;AAC7C,+BAA+B;AAC/B,yCAAsC;AAEtC,IAAA,kCAAoB,EAAgB,mBAAQ,EAAE;IAC5C,SAAS,EAAE,eAAe;IAC1B,sBAAsB,EAAE,CAAC,QAAQ,CAAC;IAClC,QAAQ,EAAE,IAAI;IACd,cAAc,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE;IACjC,OAAO,EAAE,UAAiB,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;;YAC3D,MAAM,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,IAAA,kBAAU,EAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAA,kBAAU,EAAC,UAAU,CAAC,CAAC;YAClD,IAAI,YAAY,GAAG,CAAC,CAAC;YAErB,OAAO,IAAI,EAAE;gBACX,MAAM,GAAG,GAAG,cAAM,YAAM,CAAC,4BAA4B,CAAC;oBACpD,MAAM,EAAE,MAAM;oBACd,UAAU,EAAE,UAAU;oBACtB,QAAQ,EAAE,QAAQ;oBAClB,IAAI,EAAE,YAAY;oBAClB,KAAK,EAAE,GAAG;iBACX,CAAC,CAAA,CAAC;gBACH,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE;oBAClB,MAAM,eAAe,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;iBAChD;gBACD,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,MAAM;gBAEjC,oBAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC,CAAC,EAAiB,EAAE,CAAC,CAAC;oBACrB,SAAS;oBACT,aAAa;oBACb,UAAU;oBACV,UAAU,EAAE,IAAA,kBAAU,EAAC,CAAC,CAAC,CAAC,YAAY,CAAC;oBACvC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,mBAAmB,EAAE;oBACtC,UAAU,EAAE,GAAG,CAAC,CAAC,mBAAmB,EAAE;oBACtC,gBAAgB,EAAE,EAAE;iBACrB,CAAC,CACH,CAAA,CAAC;gBACF,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ;oBAAE,MAAM;gBACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,UAAU;oBAAE,MAAM;gBACrE,YAAY,EAAE,CAAC;gBACf,cAAM,IAAA,qBAAc,EAAC,IAAA,YAAK,EAAC,IAAI,CAAC,CAAC,CAAA,CAAC;aACnC;QACH,CAAC;KAAA;CACF,CAAC,CAAC","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { createSeriesProvider } from '@yuants/data-series';\nimport { decodePath, formatTime } from '@yuants/utils';\nimport { firstValueFrom, timer } from 'rxjs';\nimport { client } from './api';\nimport { terminal } from './terminal';\n\ncreateSeriesProvider<IInterestRate>(terminal, {\n tableName: 'interest_rate',\n series_id_prefix_parts: ['coinex'],\n reversed: true,\n serviceOptions: { concurrent: 1 },\n queryFn: async function* ({ series_id, started_at, ended_at }) {\n const [datasource_id, product_id] = decodePath(series_id);\n const [instType, instId] = decodePath(product_id);\n let current_page = 0;\n\n while (true) {\n const res = await client.getFuturesFundingRateHistory({\n market: instId,\n start_time: started_at,\n end_time: ended_at,\n page: current_page,\n limit: 100,\n });\n if (res.code !== 0) {\n throw `API failed: ${res.code} ${res.message}`;\n }\n if (res.data.length === 0) break;\n\n yield res.data.map(\n (v): IInterestRate => ({\n series_id,\n datasource_id,\n product_id,\n created_at: formatTime(+v.funding_time),\n long_rate: `${-v.actual_funding_rate}`,\n short_rate: `${v.actual_funding_rate}`,\n settlement_price: '',\n }),\n );\n if (!res.pagination.has_next) break;\n if (+res.data[res.data.length - 1].funding_time <= started_at) break;\n current_page++;\n await firstValueFrom(timer(1000));\n }\n },\n});\n"]}
|
package/lib/product.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const mapSymbolToMarket$: import("rxjs").Observable<Map<string, {
|
|
2
|
+
market: string;
|
|
3
|
+
contract_type: string;
|
|
4
|
+
maker_fee_rate: string;
|
|
5
|
+
taker_fee_rate: string;
|
|
6
|
+
min_amount: string;
|
|
7
|
+
base_ccy: string;
|
|
8
|
+
quote_ccy: string;
|
|
9
|
+
base_ccy_precision: number;
|
|
10
|
+
quote_ccy_precision: number;
|
|
11
|
+
leverage: number[];
|
|
12
|
+
open_interest_volume: string;
|
|
13
|
+
}>>;
|
|
14
|
+
//# sourceMappingURL=product.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;GAiB9B,CAAC"}
|
package/lib/product.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapSymbolToMarket$ = void 0;
|
|
4
|
+
const sql_1 = require("@yuants/sql");
|
|
5
|
+
const utils_1 = require("@yuants/utils");
|
|
6
|
+
const rxjs_1 = require("rxjs");
|
|
7
|
+
const api_1 = require("./api");
|
|
8
|
+
const terminal_1 = require("./terminal");
|
|
9
|
+
const product$ = new rxjs_1.Subject();
|
|
10
|
+
exports.mapSymbolToMarket$ = (0, rxjs_1.defer)(async () => {
|
|
11
|
+
const res = await api_1.client.getFuturesMarket();
|
|
12
|
+
if (res.code !== 0) {
|
|
13
|
+
throw new Error(res.message);
|
|
14
|
+
}
|
|
15
|
+
return res.data;
|
|
16
|
+
}).pipe((0, rxjs_1.repeat)({ delay: 1000 }), (0, rxjs_1.retry)({ delay: 30000 }), (0, rxjs_1.mergeMap)((x) => (0, rxjs_1.from)(x).pipe((0, rxjs_1.map)((v) => [v.market, v]), (0, rxjs_1.toArray)(), (0, rxjs_1.map)((v) => new Map(v)))), (0, rxjs_1.shareReplay)(1));
|
|
17
|
+
const futuresProducts$ = (0, rxjs_1.defer)(async () => {
|
|
18
|
+
const res = await api_1.client.getFuturesMarket();
|
|
19
|
+
if (res.code !== 0) {
|
|
20
|
+
throw new Error(res.message);
|
|
21
|
+
}
|
|
22
|
+
const futures = res.data.map((item) => ({
|
|
23
|
+
datasource_id: 'COINEX',
|
|
24
|
+
product_id: (0, utils_1.encodePath)('SWAP', item.market),
|
|
25
|
+
quote_currency: item.quote_ccy,
|
|
26
|
+
base_currency: item.base_ccy,
|
|
27
|
+
price_step: Number(item.quote_ccy_precision),
|
|
28
|
+
// FIXME: volume_step, value_scale
|
|
29
|
+
volume_step: 1,
|
|
30
|
+
value_scale: 1,
|
|
31
|
+
name: '',
|
|
32
|
+
value_scale_unit: '',
|
|
33
|
+
margin_rate: 0,
|
|
34
|
+
value_based_cost: 0,
|
|
35
|
+
volume_based_cost: 0,
|
|
36
|
+
max_position: 0,
|
|
37
|
+
max_volume: 0,
|
|
38
|
+
allow_long: true,
|
|
39
|
+
allow_short: true,
|
|
40
|
+
}));
|
|
41
|
+
return futures;
|
|
42
|
+
}).pipe((0, rxjs_1.tap)((list) => {
|
|
43
|
+
list.forEach((v) => product$.next(v));
|
|
44
|
+
}), (0, rxjs_1.tap)({
|
|
45
|
+
error: (e) => {
|
|
46
|
+
console.error((0, utils_1.formatTime)(Date.now()), 'FuturesProducts', e);
|
|
47
|
+
},
|
|
48
|
+
}), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.repeat)({ delay: 86400000 }), (0, rxjs_1.shareReplay)(1));
|
|
49
|
+
(0, sql_1.createSQLWriter)(terminal_1.terminal, {
|
|
50
|
+
tableName: 'product',
|
|
51
|
+
data$: product$,
|
|
52
|
+
writeInterval: 1000,
|
|
53
|
+
keyFn: (x) => (0, utils_1.encodePath)(x.datasource_id, x.product_id),
|
|
54
|
+
conflictKeys: ['datasource_id', 'product_id'],
|
|
55
|
+
});
|
|
56
|
+
futuresProducts$.subscribe();
|
|
57
|
+
const mapProductIdToFuturesProduct$ = futuresProducts$.pipe(
|
|
58
|
+
//
|
|
59
|
+
(0, rxjs_1.map)((products) => new Map(products.map((v) => [v.product_id, v]))), (0, rxjs_1.shareReplay)(1));
|
|
60
|
+
//# sourceMappingURL=product.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"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","sourcesContent":["import { IProduct } from '@yuants/data-product';\nimport { createSQLWriter } from '@yuants/sql';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { defer, from, map, mergeMap, repeat, retry, shareReplay, Subject, tap, toArray } from 'rxjs';\nimport { client } from './api';\nimport { terminal } from './terminal';\n\nconst product$ = new Subject<IProduct>();\n\nexport const mapSymbolToMarket$ = defer(async () => {\n const res = await client.getFuturesMarket();\n if (res.code !== 0) {\n throw new Error(res.message);\n }\n return res.data;\n}).pipe(\n repeat({ delay: 1_000 }),\n retry({ delay: 30_000 }),\n mergeMap((x) =>\n from(x).pipe(\n map((v) => [v.market, v] as const),\n toArray(),\n map((v) => new Map(v)),\n ),\n ),\n shareReplay(1),\n);\n\nconst futuresProducts$ = defer(async () => {\n const res = await client.getFuturesMarket();\n if (res.code !== 0) {\n throw new Error(res.message);\n }\n\n const futures = res.data.map(\n (item): IProduct => ({\n datasource_id: 'COINEX',\n product_id: encodePath('SWAP', item.market),\n quote_currency: item.quote_ccy,\n base_currency: item.base_ccy,\n price_step: Number(item.quote_ccy_precision),\n // FIXME: volume_step, value_scale\n volume_step: 1,\n value_scale: 1,\n name: '',\n value_scale_unit: '',\n margin_rate: 0,\n value_based_cost: 0,\n volume_based_cost: 0,\n max_position: 0,\n max_volume: 0,\n allow_long: true,\n allow_short: true,\n }),\n );\n return futures;\n}).pipe(\n tap((list) => {\n list.forEach((v) => product$.next(v));\n }),\n tap({\n error: (e) => {\n console.error(formatTime(Date.now()), 'FuturesProducts', e);\n },\n }),\n retry({ delay: 5000 }),\n repeat({ delay: 86400_000 }),\n shareReplay(1),\n);\n\ncreateSQLWriter<IProduct>(terminal, {\n tableName: 'product',\n data$: product$,\n writeInterval: 1000,\n keyFn: (x) => encodePath(x.datasource_id, x.product_id),\n conflictKeys: ['datasource_id', 'product_id'],\n});\n\nfuturesProducts$.subscribe();\n\nconst mapProductIdToFuturesProduct$ = futuresProducts$.pipe(\n //\n map((products) => new Map(products.map((v) => [v.product_id, v]))),\n shareReplay(1),\n);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG5C,eAAO,MAAM,QAAQ,UAGnB,CAAC"}
|
package/lib/terminal.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.terminal = void 0;
|
|
4
|
+
const protocol_1 = require("@yuants/protocol");
|
|
5
|
+
const utils_1 = require("@yuants/utils");
|
|
6
|
+
exports.terminal = new protocol_1.Terminal(process.env.HOST_URL, {
|
|
7
|
+
name: 'COINEX',
|
|
8
|
+
terminal_id: process.env.TERMINAL_ID || `COINEX/${(0, utils_1.UUID)()}`,
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":";;;AAAA,+CAA4C;AAC5C,yCAAqC;AAExB,QAAA,QAAQ,GAAG,IAAI,mBAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAS,EAAE;IAC1D,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU,IAAA,YAAI,GAAE,EAAE;CAC3D,CAAC,CAAC","sourcesContent":["import { Terminal } from '@yuants/protocol';\nimport { UUID } from '@yuants/utils';\n\nexport const terminal = new Terminal(process.env.HOST_URL!, {\n name: 'COINEX',\n terminal_id: process.env.TERMINAL_ID || `COINEX/${UUID()}`,\n});\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
|
2
|
+
// It should be published with your NPM package. It should not be tracked by Git.
|
|
3
|
+
{
|
|
4
|
+
"tsdocVersion": "0.12",
|
|
5
|
+
"toolPackages": [
|
|
6
|
+
{
|
|
7
|
+
"packageName": "@microsoft/api-extractor",
|
|
8
|
+
"packageVersion": "7.30.1"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuants/vendor-coinex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"main": "lib/index.js",
|
|
5
|
+
"bin": "lib/cli.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
4
7
|
"files": [
|
|
5
|
-
"dist
|
|
8
|
+
"dist",
|
|
9
|
+
"lib",
|
|
10
|
+
"temp"
|
|
6
11
|
],
|
|
7
12
|
"dependencies": {
|
|
8
13
|
"@yuants/protocol": "0.37.2",
|
|
9
|
-
"@yuants/transfer": "0.2.
|
|
14
|
+
"@yuants/transfer": "0.2.4",
|
|
10
15
|
"@yuants/utils": "0.5.0",
|
|
11
|
-
"@yuants/sql": "0.8.
|
|
12
|
-
"@yuants/data-series": "0.3.
|
|
13
|
-
"@yuants/data-product": "0.2.
|
|
14
|
-
"@yuants/data-interest-rate": "0.1.
|
|
16
|
+
"@yuants/sql": "0.8.3",
|
|
17
|
+
"@yuants/data-series": "0.3.16",
|
|
18
|
+
"@yuants/data-product": "0.2.5",
|
|
19
|
+
"@yuants/data-interest-rate": "0.1.13",
|
|
15
20
|
"rxjs": "~7.5.6",
|
|
16
21
|
"crypto-js": "^4.2.0"
|
|
17
22
|
},
|
package/temp/image-tag
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sha-c05cdffc4bcffa48d80b2fd971d51883be9272aa
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apps/vendor-coinex/CHANGELOG.json": "de882985e80e73af990a472086134bb765818b27",
|
|
3
|
+
"apps/vendor-coinex/CHANGELOG.md": "51b5a0faa8d1c9555e68d16d2460fe5a8a6ffa17",
|
|
4
|
+
"apps/vendor-coinex/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
|
|
5
|
+
"apps/vendor-coinex/build/Dockerfile": "8337903e3366ea6c13f1396269c082b8cb5dd96b",
|
|
6
|
+
"apps/vendor-coinex/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
|
|
7
|
+
"apps/vendor-coinex/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
|
8
|
+
"apps/vendor-coinex/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
|
9
|
+
"apps/vendor-coinex/etc/vendor-coinex.api.md": "33941b70ac7469421ff8fb8c157181014a0ea655",
|
|
10
|
+
"apps/vendor-coinex/package.json": "df74ce267420f8b9ab3cc06ed8dbce8b25eb603d",
|
|
11
|
+
"apps/vendor-coinex/src/api.ts": "5dc2027855a6f71ff98f88ad2329abeef40593fb",
|
|
12
|
+
"apps/vendor-coinex/src/cli.ts": "9bf6b5559a6c6f33da20e74cc6c5d702c60ec891",
|
|
13
|
+
"apps/vendor-coinex/src/extension.ts": "0a560546d341acebb59b1703be89c19fc2111a8b",
|
|
14
|
+
"apps/vendor-coinex/src/index.ts": "1839b7a344b0f693f8e835f048a0bf6a69f5ff60",
|
|
15
|
+
"apps/vendor-coinex/src/interest_rate.ts": "e085bb282420c139fd541f7fa8fb9a676121382f",
|
|
16
|
+
"apps/vendor-coinex/src/product.ts": "415c59cf5fa9f56fae7b75978eb6b5b35e21748f",
|
|
17
|
+
"apps/vendor-coinex/src/terminal.ts": "c3e598a4dd29804c269bea2846d30387afd9f1cc",
|
|
18
|
+
"apps/vendor-coinex/tsconfig.json": "81da8f78196974b5d15da0edb6b2d9f48641063c",
|
|
19
|
+
"apps/vendor-coinex/.rush/temp/shrinkwrap-deps.json": "65091c107a6149901dadc3fa1a7717446ce94f99",
|
|
20
|
+
"libraries/protocol/temp/package-deps.json": "d326f24867d9ae3fef16ff84ba537eabb7c8adf0",
|
|
21
|
+
"libraries/transfer/temp/package-deps.json": "cb2786055e5e79cd7d9d0f5787e300ca1c0bf002",
|
|
22
|
+
"libraries/utils/temp/package-deps.json": "c747617da1c0a40843603c62a7477da641ff0aef",
|
|
23
|
+
"libraries/sql/temp/package-deps.json": "1cb2248873d01ed732e8473f7b242a41f987fdd7",
|
|
24
|
+
"libraries/data-series/temp/package-deps.json": "3ba9330800ae3952ed7ba430526596a24d1e8eb7",
|
|
25
|
+
"libraries/data-product/temp/package-deps.json": "634e636d948295079b02dbeffb84f6d52872fda8",
|
|
26
|
+
"libraries/data-interest-rate/temp/package-deps.json": "420702140b635d7fbbd0524108a827b12efde639",
|
|
27
|
+
"libraries/extension/temp/package-deps.json": "96816518ae9dc050cafe0b8fbce95cbb59d06ee6",
|
|
28
|
+
"tools/toolkit/temp/package-deps.json": "eb0447c467da3a90db0913ed01e42ec0de840234"
|
|
29
|
+
}
|