@yuants/app-virtual-exchange 0.6.0 → 0.7.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/general.js +5 -1
- package/dist/general.js.map +1 -1
- package/dist/position.js +12 -1
- package/dist/position.js.map +1 -1
- package/lib/general.js +5 -1
- package/lib/general.js.map +1 -1
- package/lib/position.d.ts.map +1 -1
- package/lib/position.js +12 -1
- package/lib/position.js.map +1 -1
- package/package.json +3 -3
- package/temp/package-deps.json +7 -7
package/dist/general.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';
|
|
2
2
|
import { Terminal } from '@yuants/protocol';
|
|
3
3
|
import { getCredentialBySecretId } from './credential';
|
|
4
|
+
import { polyfillPosition } from './position';
|
|
4
5
|
const terminal = Terminal.fromNodeEnv();
|
|
5
6
|
terminal.server.provideService('VEX/GetPositions', {
|
|
6
7
|
type: 'object',
|
|
@@ -12,7 +13,10 @@ terminal.server.provideService('VEX/GetPositions', {
|
|
|
12
13
|
}, async (msg) => {
|
|
13
14
|
const credential = await getCredentialBySecretId(msg.req.secret_id);
|
|
14
15
|
const res = await getPositions(terminal, credential.credential, msg.req.product_id);
|
|
15
|
-
|
|
16
|
+
if (!res.data)
|
|
17
|
+
return { res };
|
|
18
|
+
const positions = await polyfillPosition(res.data);
|
|
19
|
+
return { res: { code: 0, message: 'OK', data: positions } };
|
|
16
20
|
});
|
|
17
21
|
terminal.server.provideService('VEX/GetOrders', {
|
|
18
22
|
type: 'object',
|
package/dist/general.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { getCredentialBySecretId } from './credential';\nimport { polyfillPosition } from './position';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IPosition[]>(\n 'VEX/GetPositions',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getPositions(terminal, credential.credential, msg.req.product_id);\n if (!res.data) return { res };\n const positions = await polyfillPosition(res.data);\n return { res: { code: 0, message: 'OK', data: positions } };\n },\n);\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IOrder[]>(\n 'VEX/GetOrders',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getOrders(terminal, credential.credential, msg.req.product_id);\n res.data?.forEach((order) => {\n order.account_id = credential.credentialId;\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, { order_id: string }>(\n 'VEX/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await submitOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await modifyOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/CancelOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await cancelOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n"]}
|
package/dist/position.js
CHANGED
|
@@ -9,12 +9,20 @@ const quoteCache = createCache(async (product_id) => {
|
|
|
9
9
|
const [quote] = await requestSQL(terminal, sql);
|
|
10
10
|
return quote;
|
|
11
11
|
}, { expire: 30000 });
|
|
12
|
+
const interestRateIntervalCache = createCache(async (product_id) => {
|
|
13
|
+
const sql = `select created_at from interest_rate where series_id = ${escapeSQL(product_id)} order by created_at desc limit 2`;
|
|
14
|
+
const rates = await requestSQL(terminal, sql);
|
|
15
|
+
if (rates.length < 2)
|
|
16
|
+
return undefined;
|
|
17
|
+
return new Date(rates[0].created_at).getTime() - new Date(rates[1].created_at).getTime();
|
|
18
|
+
});
|
|
12
19
|
export const polyfillPosition = async (positions) => {
|
|
13
20
|
// TODO: 使用 batch query SQL 优化 product / quote 查询性能
|
|
14
21
|
for (const pos of positions) {
|
|
15
|
-
const [theProduct, quote] = await Promise.all([
|
|
22
|
+
const [theProduct, quote, interestRateInterval] = await Promise.all([
|
|
16
23
|
productCache.query(pos.product_id),
|
|
17
24
|
quoteCache.query(pos.product_id),
|
|
25
|
+
interestRateIntervalCache.query(pos.product_id),
|
|
18
26
|
]);
|
|
19
27
|
// 估值 = value_scale * volume * closable_price
|
|
20
28
|
if (theProduct) {
|
|
@@ -49,6 +57,9 @@ export const polyfillPosition = async (positions) => {
|
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
59
|
}
|
|
60
|
+
if (interestRateInterval) {
|
|
61
|
+
pos.settlement_interval = interestRateInterval;
|
|
62
|
+
}
|
|
52
63
|
}
|
|
53
64
|
return positions;
|
|
54
65
|
};
|
package/dist/position.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;AACxD,MAAM,UAAU,GAAG,WAAW,CAC5B,KAAK,EAAE,UAAU,EAAE,EAAE;IACnB,MAAM,GAAG,GAAG,0CAA0C,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAC9E,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,UAAU,CAAW,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC;AACf,CAAC,EACD,EAAE,MAAM,EAAE,KAAM,EAAE,CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAsB,EAAwB,EAAE;IACrF,mDAAmD;IACnD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE;QAC3B,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n return new Date(rates[0].created_at).getTime() - new Date(rates[1].created_at).getTime();\n});\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n // 利率相关信息的追加\n if (quote) {\n if (quote.interest_rate_next_settled_at !== null) {\n pos.settlement_scheduled_at = new Date(quote.interest_rate_next_settled_at).getTime();\n }\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n\n if (interestRateInterval) {\n pos.settlement_interval = interestRateInterval;\n }\n }\n return positions;\n};\n"]}
|
package/lib/general.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const exchange_1 = require("@yuants/exchange");
|
|
4
4
|
const protocol_1 = require("@yuants/protocol");
|
|
5
5
|
const credential_1 = require("./credential");
|
|
6
|
+
const position_1 = require("./position");
|
|
6
7
|
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
7
8
|
terminal.server.provideService('VEX/GetPositions', {
|
|
8
9
|
type: 'object',
|
|
@@ -14,7 +15,10 @@ terminal.server.provideService('VEX/GetPositions', {
|
|
|
14
15
|
}, async (msg) => {
|
|
15
16
|
const credential = await (0, credential_1.getCredentialBySecretId)(msg.req.secret_id);
|
|
16
17
|
const res = await (0, exchange_1.getPositions)(terminal, credential.credential, msg.req.product_id);
|
|
17
|
-
|
|
18
|
+
if (!res.data)
|
|
19
|
+
return { res };
|
|
20
|
+
const positions = await (0, position_1.polyfillPosition)(res.data);
|
|
21
|
+
return { res: { code: 0, message: 'OK', data: positions } };
|
|
18
22
|
});
|
|
19
23
|
terminal.server.provideService('VEX/GetOrders', {
|
|
20
24
|
type: 'object',
|
package/lib/general.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":";;AAEA,+CAAkG;AAClG,+CAA4C;AAC5C,6CAAuD;
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { getCredentialBySecretId } from './credential';\nimport { polyfillPosition } from './position';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IPosition[]>(\n 'VEX/GetPositions',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getPositions(terminal, credential.credential, msg.req.product_id);\n if (!res.data) return { res };\n const positions = await polyfillPosition(res.data);\n return { res: { code: 0, message: 'OK', data: positions } };\n },\n);\n\nterminal.server.provideService<{ secret_id: string; product_id?: string }, IOrder[]>(\n 'VEX/GetOrders',\n {\n type: 'object',\n required: ['secret_id'],\n properties: {\n secret_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await getOrders(terminal, credential.credential, msg.req.product_id);\n res.data?.forEach((order) => {\n order.account_id = credential.credentialId;\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, { order_id: string }>(\n 'VEX/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await submitOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await modifyOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; secret_id: string }, void>(\n 'VEX/CancelOrder',\n {\n type: 'object',\n required: ['order', 'secret_id'],\n properties: {\n order: { type: 'object' },\n secret_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialBySecretId(msg.req.secret_id);\n const res = await cancelOrder(terminal, credential.credential, msg.req.order);\n return { res };\n },\n);\n"]}
|
package/lib/position.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AA0BjD,eAAO,MAAM,gBAAgB,cAAqB,SAAS,EAAE,KAAG,QAAQ,SAAS,EAAE,CAiDlF,CAAC"}
|
package/lib/position.js
CHANGED
|
@@ -12,12 +12,20 @@ const quoteCache = (0, cache_1.createCache)(async (product_id) => {
|
|
|
12
12
|
const [quote] = await (0, sql_1.requestSQL)(terminal, sql);
|
|
13
13
|
return quote;
|
|
14
14
|
}, { expire: 30000 });
|
|
15
|
+
const interestRateIntervalCache = (0, cache_1.createCache)(async (product_id) => {
|
|
16
|
+
const sql = `select created_at from interest_rate where series_id = ${(0, sql_1.escapeSQL)(product_id)} order by created_at desc limit 2`;
|
|
17
|
+
const rates = await (0, sql_1.requestSQL)(terminal, sql);
|
|
18
|
+
if (rates.length < 2)
|
|
19
|
+
return undefined;
|
|
20
|
+
return new Date(rates[0].created_at).getTime() - new Date(rates[1].created_at).getTime();
|
|
21
|
+
});
|
|
15
22
|
const polyfillPosition = async (positions) => {
|
|
16
23
|
// TODO: 使用 batch query SQL 优化 product / quote 查询性能
|
|
17
24
|
for (const pos of positions) {
|
|
18
|
-
const [theProduct, quote] = await Promise.all([
|
|
25
|
+
const [theProduct, quote, interestRateInterval] = await Promise.all([
|
|
19
26
|
productCache.query(pos.product_id),
|
|
20
27
|
quoteCache.query(pos.product_id),
|
|
28
|
+
interestRateIntervalCache.query(pos.product_id),
|
|
21
29
|
]);
|
|
22
30
|
// 估值 = value_scale * volume * closable_price
|
|
23
31
|
if (theProduct) {
|
|
@@ -52,6 +60,9 @@ const polyfillPosition = async (positions) => {
|
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
}
|
|
63
|
+
if (interestRateInterval) {
|
|
64
|
+
pos.settlement_interval = interestRateInterval;
|
|
65
|
+
}
|
|
55
66
|
}
|
|
56
67
|
return positions;
|
|
57
68
|
};
|
package/lib/position.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":";;;AAAA,yCAA4C;AAE5C,uDAAgE;AAEhE,+CAA4C;AAC5C,qCAAoD;AAEpD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AACxC,MAAM,YAAY,GAAG,IAAA,uCAAwB,EAAC,QAAQ,CAAC,CAAC;AACxD,MAAM,UAAU,GAAG,IAAA,mBAAW,EAC5B,KAAK,EAAE,UAAU,EAAE,EAAE;IACnB,MAAM,GAAG,GAAG,0CAA0C,IAAA,eAAS,EAAC,UAAU,CAAC,EAAE,CAAC;IAC9E,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAA,gBAAU,EAAW,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC1D,OAAO,KAAK,CAAC;AACf,CAAC,EACD,EAAE,MAAM,EAAE,KAAM,EAAE,CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCache } from '@yuants/cache';\nimport { IPosition } from '@yuants/data-account';\nimport { createClientProductCache } from '@yuants/data-product';\nimport { IQuote } from '@yuants/data-quote';\nimport { Terminal } from '@yuants/protocol';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\n\nconst terminal = Terminal.fromNodeEnv();\nconst productCache = createClientProductCache(terminal);\nconst quoteCache = createCache<IQuote>(\n async (product_id) => {\n const sql = `select * from quote where product_id = ${escapeSQL(product_id)}`;\n const [quote] = await requestSQL<IQuote[]>(terminal, sql);\n return quote;\n },\n { expire: 30_000 },\n);\n\nconst interestRateIntervalCache = createCache(async (product_id: string) => {\n const sql = `select created_at from interest_rate where series_id = ${escapeSQL(\n product_id,\n )} order by created_at desc limit 2`;\n const rates = await requestSQL<{ created_at: string }[]>(terminal, sql);\n if (rates.length < 2) return undefined;\n return new Date(rates[0].created_at).getTime() - new Date(rates[1].created_at).getTime();\n});\n\nexport const polyfillPosition = async (positions: IPosition[]): Promise<IPosition[]> => {\n // TODO: 使用 batch query SQL 优化 product / quote 查询性能\n for (const pos of positions) {\n const [theProduct, quote, interestRateInterval] = await Promise.all([\n productCache.query(pos.product_id),\n quoteCache.query(pos.product_id),\n interestRateIntervalCache.query(pos.product_id),\n ]);\n\n // 估值 = value_scale * volume * closable_price\n if (theProduct) {\n if (theProduct.base_currency) {\n pos.base_currency = theProduct.base_currency;\n }\n if (theProduct.quote_currency) {\n pos.quote_currency = theProduct.quote_currency;\n }\n if (pos.size === undefined && pos.volume !== undefined && pos.direction !== undefined) {\n pos.size = (pos.direction === 'LONG' ? 1 : -1) * pos.volume * (theProduct.value_scale || 1) + '';\n }\n if (pos.free_size === undefined && pos.free_volume !== undefined && pos.direction !== undefined) {\n pos.free_size =\n (pos.direction === 'LONG' ? 1 : -1) * pos.free_volume * (theProduct.value_scale || 1) + '';\n }\n pos.valuation = Math.abs((theProduct.value_scale || 1) * pos.volume * pos.closable_price);\n }\n\n // 利率相关信息的追加\n if (quote) {\n if (quote.interest_rate_next_settled_at !== null) {\n pos.settlement_scheduled_at = new Date(quote.interest_rate_next_settled_at).getTime();\n }\n if (pos.direction === 'LONG') {\n if (quote.interest_rate_long !== null) {\n pos.interest_to_settle = +quote.interest_rate_long * pos.valuation;\n }\n }\n if (pos.direction === 'SHORT') {\n if (quote.interest_rate_short !== null) {\n pos.interest_to_settle = +quote.interest_rate_short * pos.valuation;\n }\n }\n }\n\n if (interestRateInterval) {\n pos.settlement_interval = interestRateInterval;\n }\n }\n return positions;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuants/app-virtual-exchange",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"@yuants/protocol": "0.53.2",
|
|
12
12
|
"@yuants/utils": "0.14.0",
|
|
13
13
|
"@yuants/data-product": "0.5.0",
|
|
14
|
-
"@yuants/data-account": "0.
|
|
14
|
+
"@yuants/data-account": "0.10.0",
|
|
15
15
|
"@yuants/data-order": "0.6.6",
|
|
16
16
|
"@yuants/data-quote": "0.2.43",
|
|
17
17
|
"@yuants/secret": "0.3.13",
|
|
18
18
|
"@yuants/sql": "0.9.30",
|
|
19
|
-
"@yuants/exchange": "0.
|
|
19
|
+
"@yuants/exchange": "0.5.0",
|
|
20
20
|
"@yuants/cache": "0.3.3",
|
|
21
21
|
"rxjs": "~7.5.6",
|
|
22
22
|
"ajv": "~8.12.0"
|
package/temp/package-deps.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apps/virtual-exchange/CHANGELOG.json": "
|
|
3
|
-
"apps/virtual-exchange/CHANGELOG.md": "
|
|
2
|
+
"apps/virtual-exchange/CHANGELOG.json": "e97010395e2916eeb7047426c7d217dd2b1405df",
|
|
3
|
+
"apps/virtual-exchange/CHANGELOG.md": "8bb205ea50a3c711d70c6dde68a1ef7a41d14d2c",
|
|
4
4
|
"apps/virtual-exchange/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
|
|
5
5
|
"apps/virtual-exchange/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
|
|
6
6
|
"apps/virtual-exchange/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
|
7
7
|
"apps/virtual-exchange/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
|
8
8
|
"apps/virtual-exchange/etc/app-virtual-exchange.api.md": "6cb40ec1fa2d40a31a7b0dd3f02b8b24a4d7c4de",
|
|
9
|
-
"apps/virtual-exchange/package.json": "
|
|
9
|
+
"apps/virtual-exchange/package.json": "7aa18dbb6758249c32aa918ddb21dab95f5fdbb2",
|
|
10
10
|
"apps/virtual-exchange/src/credential.ts": "f839246750fcbddd9a6a29bf3de54631a92c88b7",
|
|
11
|
-
"apps/virtual-exchange/src/general.ts": "
|
|
11
|
+
"apps/virtual-exchange/src/general.ts": "16a234c6ddbdf33490339272579cbcbac17e048c",
|
|
12
12
|
"apps/virtual-exchange/src/index.ts": "8d7f19a07e6be09c4d8fd4a49ddb3127d3fbf3de",
|
|
13
13
|
"apps/virtual-exchange/src/legacy-services.ts": "73f57566054e8cae899dc20f4d1547184e2c2e71",
|
|
14
|
-
"apps/virtual-exchange/src/position.ts": "
|
|
14
|
+
"apps/virtual-exchange/src/position.ts": "19b4c6ff99b13a3bc2fc0de70ba5352a3ae9f499",
|
|
15
15
|
"apps/virtual-exchange/src/product-collector.ts": "15ba0a692d694d20b607eaad0287a864577ef30c",
|
|
16
16
|
"apps/virtual-exchange/tsconfig.json": "22f94ca28b507f8ddcc21b9053158eefd3f726a9",
|
|
17
17
|
"apps/virtual-exchange/.rush/temp/shrinkwrap-deps.json": "2c8344167a574161e8a89138bc1eb686bf6339de",
|
|
18
18
|
"libraries/protocol/temp/package-deps.json": "0bd43721e96039b52d7b59c834dc6df45cf75e3f",
|
|
19
19
|
"libraries/utils/temp/package-deps.json": "6d58e9b325e8d16de8a878c32010f626b12a01da",
|
|
20
20
|
"libraries/data-product/temp/package-deps.json": "a03f08f30800d5fb52c5d019bda4f8e7ec04e344",
|
|
21
|
-
"libraries/data-account/temp/package-deps.json": "
|
|
21
|
+
"libraries/data-account/temp/package-deps.json": "3ee766acef866410612b60dfc1012082c9c24556",
|
|
22
22
|
"libraries/data-order/temp/package-deps.json": "2adac9fc0423f9b1b7ddaa8946ab7af374cc22e1",
|
|
23
23
|
"libraries/data-quote/temp/package-deps.json": "34d079eab44d2bf65e07b112ac2099c6e92a015e",
|
|
24
24
|
"libraries/secret/temp/package-deps.json": "d7bea10938c76e2e654781b013cc7be5eaa04ede",
|
|
25
25
|
"libraries/sql/temp/package-deps.json": "4a9a7ec55f04b20459e664e81e76fa74b6c77b39",
|
|
26
|
-
"libraries/exchange/temp/package-deps.json": "
|
|
26
|
+
"libraries/exchange/temp/package-deps.json": "d40288d0530bc7e63246f234bdffa10a497776b1",
|
|
27
27
|
"libraries/cache/temp/package-deps.json": "a4afa15e6462983f9d3735d31dc1ed8a683fb4dc",
|
|
28
28
|
"tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
|
|
29
29
|
}
|