@yuants/exchange 0.7.1 → 0.8.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.
Files changed (45) hide show
  1. package/dist/exchange.d.ts +88 -0
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/interest_rate.js +128 -0
  5. package/dist/interest_rate.js.map +1 -0
  6. package/dist/interest_rate.test.js +24 -0
  7. package/dist/interest_rate.test.js.map +1 -0
  8. package/dist/ohlc.js +153 -0
  9. package/dist/ohlc.js.map +1 -0
  10. package/dist/ohlc.test.js +26 -0
  11. package/dist/ohlc.test.js.map +1 -0
  12. package/dist/quote.test.js +31 -0
  13. package/dist/quote.test.js.map +1 -0
  14. package/dist/types.js.map +1 -1
  15. package/lib/index.d.ts +2 -0
  16. package/lib/index.d.ts.map +1 -1
  17. package/lib/index.js +2 -0
  18. package/lib/index.js.map +1 -1
  19. package/lib/interest_rate.d.ts +33 -0
  20. package/lib/interest_rate.d.ts.map +1 -0
  21. package/lib/interest_rate.js +133 -0
  22. package/lib/interest_rate.js.map +1 -0
  23. package/lib/interest_rate.test.d.ts +2 -0
  24. package/lib/interest_rate.test.d.ts.map +1 -0
  25. package/lib/interest_rate.test.js +26 -0
  26. package/lib/interest_rate.test.js.map +1 -0
  27. package/lib/ohlc.d.ts +35 -0
  28. package/lib/ohlc.d.ts.map +1 -0
  29. package/lib/ohlc.js +158 -0
  30. package/lib/ohlc.js.map +1 -0
  31. package/lib/ohlc.test.d.ts +2 -0
  32. package/lib/ohlc.test.d.ts.map +1 -0
  33. package/lib/ohlc.test.js +28 -0
  34. package/lib/ohlc.test.js.map +1 -0
  35. package/lib/quote.test.d.ts +2 -0
  36. package/lib/quote.test.d.ts.map +1 -0
  37. package/lib/quote.test.js +33 -0
  38. package/lib/quote.test.js.map +1 -0
  39. package/lib/types.d.ts +16 -0
  40. package/lib/types.d.ts.map +1 -1
  41. package/lib/types.js.map +1 -1
  42. package/package.json +3 -1
  43. package/temp/exchange.api.json +698 -0
  44. package/temp/exchange.api.md +76 -0
  45. package/temp/package-deps.json +14 -7
@@ -1,3 +1,5 @@
1
+ import { IInterestRate } from '@yuants/data-interest-rate';
2
+ import { IOHLC } from '@yuants/data-ohlc';
1
3
  import { IOrder } from '@yuants/data-order';
2
4
  import { IPosition } from '@yuants/data-account';
3
5
  import { IProduct } from '@yuants/data-product';
@@ -122,6 +124,46 @@ export declare interface IExchange<T = any> {
122
124
  cancelOrder(credential: T, order: IOrder): Promise<void>;
123
125
  }
124
126
 
127
+ /**
128
+ * Interest Rate Service Request from VEX to Vendor
129
+ * @public
130
+ */
131
+ export declare interface IIngestInterestRateRequest {
132
+ product_id: string;
133
+ direction: SeriesFetchDirection;
134
+ time: number;
135
+ }
136
+
137
+ /**
138
+ * OHLC Service Request from VEX to Vendor
139
+ * @public
140
+ */
141
+ export declare interface IIngestOHLCRequest {
142
+ product_id: string;
143
+ duration: string;
144
+ direction: SeriesFetchDirection;
145
+ time: number;
146
+ }
147
+
148
+ /**
149
+ * Interest Rate Service Metadata
150
+ * @public
151
+ */
152
+ export declare interface IInterestRateServiceMetadata {
153
+ product_id_prefix: string;
154
+ direction: SeriesFetchDirection;
155
+ }
156
+
157
+ /**
158
+ * OHLC Service Metadata
159
+ * @public
160
+ */
161
+ export declare interface IOHLCServiceMetadata {
162
+ product_id_prefix: string;
163
+ duration_list: string[];
164
+ direction: SeriesFetchDirection;
165
+ }
166
+
125
167
  /**
126
168
  * Quote 字段类型,排除掉 product_id, updated_at, datasource_id 三个字段
127
169
  * @public
@@ -169,6 +211,18 @@ export declare interface IQuoteServiceRequestByVEX {
169
211
  */
170
212
  export declare type IQuoteUpdateAction<K extends IQuoteField = IQuoteField> = Record<string, Partial<Record<K, [value: string, updated_at: number]>>>;
171
213
 
214
+ /**
215
+ * 历史数据写库结果(不返回数据本体)
216
+ * @public
217
+ */
218
+ export declare interface ISeriesIngestResult {
219
+ wrote_count: number;
220
+ range?: {
221
+ start_time: string;
222
+ end_time: string;
223
+ };
224
+ }
225
+
172
226
  /**
173
227
  * List products
174
228
  *
@@ -186,6 +240,16 @@ export declare const modifyOrder: <T>(terminal: Terminal, credential: {
186
240
  payload: T;
187
241
  }, order: IOrder) => Promise<IResponse<void>>;
188
242
 
243
+ /**
244
+ * @public
245
+ */
246
+ export declare const parseInterestRateServiceMetadataFromSchema: (schema: any) => IInterestRateServiceMetadata;
247
+
248
+ /**
249
+ * @public
250
+ */
251
+ export declare const parseOHLCServiceMetadataFromSchema: (schema: any) => IOHLCServiceMetadata;
252
+
189
253
  /**
190
254
  * Extract Quote Service Metadata from JSON Schema
191
255
  * @public
@@ -199,6 +263,24 @@ export declare const parseQuoteServiceMetadataFromSchema: (schema: any) => IQuot
199
263
  */
200
264
  export declare const provideExchangeServices: <T>(terminal: Terminal, exchange: IExchange<T>) => void;
201
265
 
266
+ /**
267
+ * @public
268
+ */
269
+ export declare const provideInterestRateService: (terminal: Terminal, metadata: IInterestRateServiceMetadata, fetchPage: (request: IIngestInterestRateRequest & {
270
+ series_id: string;
271
+ }) => Promise<IInterestRate[]>, serviceOptions?: IServiceOptions) => {
272
+ dispose: () => void;
273
+ };
274
+
275
+ /**
276
+ * @public
277
+ */
278
+ export declare const provideOHLCService: (terminal: Terminal, metadata: IOHLCServiceMetadata, fetchPage: (request: IIngestOHLCRequest & {
279
+ series_id: string;
280
+ }) => Promise<IOHLC[]>, serviceOptions?: IServiceOptions) => {
281
+ dispose: () => void;
282
+ };
283
+
202
284
  /**
203
285
  * Provide Quote Service
204
286
  * @public
@@ -210,6 +292,12 @@ export declare const provideQuoteService: <K extends IQuoteField>(terminal: Term
210
292
  dispose: () => void;
211
293
  };
212
294
 
295
+ /**
296
+ * 历史数据翻页方向
297
+ * @public
298
+ */
299
+ export declare type SeriesFetchDirection = 'backward' | 'forward';
300
+
213
301
  /**
214
302
  * Submit order
215
303
  *
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from './quote';
2
+ export * from './ohlc';
3
+ export * from './interest_rate';
2
4
  export * from './types';
3
5
  const makeCredentialSchema = (type, payloadSchema) => {
4
6
  return {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { IProduct } from '@yuants/data-product';\nimport { IResponse, Terminal } from '@yuants/protocol';\nimport { JSONSchema7 } from 'json-schema';\nexport * from './quote';\nexport * from './types';\n\n/**\n * Exchange Interface\n *\n * @public\n */\nexport interface IExchange<T = any> {\n /**\n * Exchange name / type (e.g. 'Binance', 'OKX')\n */\n name: string;\n\n /**\n * JSON Schema for the credential payload\n */\n credentialSchema: JSONSchema7;\n\n /**\n * Get credential ID from credential\n *\n * @param credential - The credential object\n */\n getCredentialId(credential: T): Promise<string>;\n\n /**\n * List all products\n */\n listProducts(): Promise<IProduct[]>;\n\n /**\n * Get all positions\n *\n * @param credential - The credential object\n */\n getPositions(credential: T): Promise<IPosition[]>;\n\n /**\n * Get all orders\n *\n * @param credential - The credential object\n */\n getOrders(credential: T): Promise<IOrder[]>;\n\n /**\n * Get positions by product_id\n *\n * @param credential - The credential object\n * @param product_id - The product ID\n */\n getPositionsByProductId(credential: T, product_id: string): Promise<IPosition[]>;\n\n /**\n * Get orders by product_id\n *\n * @param credential - The credential object\n * @param product_id - The product ID\n */\n getOrdersByProductId(credential: T, product_id: string): Promise<IOrder[]>;\n\n /**\n * Submit an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n submitOrder(credential: T, order: IOrder): Promise<{ order_id: string }>;\n\n /**\n * Modify an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n modifyOrder(credential: T, order: IOrder): Promise<void>;\n\n /**\n * Cancel an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n cancelOrder(credential: T, order: IOrder): Promise<void>;\n}\n\nconst makeCredentialSchema = (type: string, payloadSchema: JSONSchema7): JSONSchema7 => {\n return {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: type },\n payload: payloadSchema,\n },\n };\n};\n\n/**\n * Provide exchange services\n *\n * @public\n */\nexport const provideExchangeServices = <T>(terminal: Terminal, exchange: IExchange<T>) => {\n const { name: type, credentialSchema } = exchange;\n\n // GetCredentialId\n terminal.server.provideService<{ credential: { type: string; payload: T } }, string>(\n 'GetCredentialId',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n },\n },\n async (msg) => {\n const credentialId = await exchange.getCredentialId(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: credentialId } };\n },\n );\n\n // ListProducts\n terminal.server.provideService<void, IProduct[]>(\n 'ListProducts',\n {\n type: 'object',\n required: ['type'],\n properties: {\n type: { const: exchange.name },\n },\n },\n async () => {\n const products = await exchange.listProducts();\n return { res: { code: 0, message: 'OK', data: products } };\n },\n );\n\n // GetPositions\n terminal.server.provideService<\n { credential: { type: string; payload: T }; product_id?: string },\n IPosition[]\n >(\n 'GetPositions',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n if (msg.req.product_id) {\n const positions = await exchange.getPositionsByProductId(\n msg.req.credential.payload,\n msg.req.product_id,\n );\n return { res: { code: 0, message: 'OK', data: positions } };\n }\n const positions = await exchange.getPositions(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: positions } };\n },\n );\n\n // GetOrders\n terminal.server.provideService<{ credential: { type: string; payload: T }; product_id?: string }, IOrder[]>(\n 'GetOrders',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n if (msg.req.product_id) {\n const orders = await exchange.getOrdersByProductId(msg.req.credential.payload, msg.req.product_id);\n return { res: { code: 0, message: 'OK', data: orders } };\n }\n const orders = await exchange.getOrders(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: orders } };\n },\n );\n\n // SubmitOrder\n terminal.server.provideService<\n { credential: { type: string; payload: T }; order: IOrder },\n { order_id: string }\n >(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n const result = await exchange.submitOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK', data: result } };\n },\n );\n\n // ModifyOrder\n terminal.server.provideService<{ credential: { type: string; payload: T }; order: IOrder }, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n await exchange.modifyOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK' } };\n },\n );\n\n // CancelOrder\n terminal.server.provideService<{ credential: { type: string; payload: T }; order: IOrder }, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n await exchange.cancelOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK' } };\n },\n );\n};\n\n/**\n * Get credential ID\n *\n * @public\n */\nexport const getCredentialId = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n): Promise<IResponse<string>> => {\n return terminal.client.requestForResponse('GetCredentialId', { credential });\n};\n\n/**\n * List products\n *\n * @public\n */\nexport const listProducts = async (terminal: Terminal, type: string): Promise<IResponse<IProduct[]>> => {\n return terminal.client.requestForResponse('ListProducts', { type });\n};\n\n/**\n * Get positions\n *\n * @public\n */\nexport const getPositions = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n product_id?: string,\n): Promise<IResponse<IPosition[]>> => {\n return terminal.client.requestForResponse('GetPositions', { credential, product_id });\n};\n\n/**\n * Get orders\n *\n * @public\n */\nexport const getOrders = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n product_id?: string,\n): Promise<IResponse<IOrder[]>> => {\n return terminal.client.requestForResponse('GetOrders', { credential, product_id });\n};\n\n/**\n * Submit order\n *\n * @public\n */\nexport const submitOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<{ order_id: string }>> => {\n return terminal.client.requestForResponse('SubmitOrder', { credential, order });\n};\n\n/**\n * Modify order\n *\n * @public\n */\nexport const modifyOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<void>> => {\n return terminal.client.requestForResponse('ModifyOrder', { credential, order });\n};\n\n/**\n * Cancel order\n *\n * @public\n */\nexport const cancelOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<void>> => {\n return terminal.client.requestForResponse('CancelOrder', { credential, order });\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { IProduct } from '@yuants/data-product';\nimport { IResponse, Terminal } from '@yuants/protocol';\nimport { JSONSchema7 } from 'json-schema';\nexport * from './quote';\nexport * from './ohlc';\nexport * from './interest_rate';\nexport * from './types';\n\n/**\n * Exchange Interface\n *\n * @public\n */\nexport interface IExchange<T = any> {\n /**\n * Exchange name / type (e.g. 'Binance', 'OKX')\n */\n name: string;\n\n /**\n * JSON Schema for the credential payload\n */\n credentialSchema: JSONSchema7;\n\n /**\n * Get credential ID from credential\n *\n * @param credential - The credential object\n */\n getCredentialId(credential: T): Promise<string>;\n\n /**\n * List all products\n */\n listProducts(): Promise<IProduct[]>;\n\n /**\n * Get all positions\n *\n * @param credential - The credential object\n */\n getPositions(credential: T): Promise<IPosition[]>;\n\n /**\n * Get all orders\n *\n * @param credential - The credential object\n */\n getOrders(credential: T): Promise<IOrder[]>;\n\n /**\n * Get positions by product_id\n *\n * @param credential - The credential object\n * @param product_id - The product ID\n */\n getPositionsByProductId(credential: T, product_id: string): Promise<IPosition[]>;\n\n /**\n * Get orders by product_id\n *\n * @param credential - The credential object\n * @param product_id - The product ID\n */\n getOrdersByProductId(credential: T, product_id: string): Promise<IOrder[]>;\n\n /**\n * Submit an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n submitOrder(credential: T, order: IOrder): Promise<{ order_id: string }>;\n\n /**\n * Modify an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n modifyOrder(credential: T, order: IOrder): Promise<void>;\n\n /**\n * Cancel an order\n *\n * @param credential - The credential object\n * @param order - The order object\n */\n cancelOrder(credential: T, order: IOrder): Promise<void>;\n}\n\nconst makeCredentialSchema = (type: string, payloadSchema: JSONSchema7): JSONSchema7 => {\n return {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string', const: type },\n payload: payloadSchema,\n },\n };\n};\n\n/**\n * Provide exchange services\n *\n * @public\n */\nexport const provideExchangeServices = <T>(terminal: Terminal, exchange: IExchange<T>) => {\n const { name: type, credentialSchema } = exchange;\n\n // GetCredentialId\n terminal.server.provideService<{ credential: { type: string; payload: T } }, string>(\n 'GetCredentialId',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n },\n },\n async (msg) => {\n const credentialId = await exchange.getCredentialId(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: credentialId } };\n },\n );\n\n // ListProducts\n terminal.server.provideService<void, IProduct[]>(\n 'ListProducts',\n {\n type: 'object',\n required: ['type'],\n properties: {\n type: { const: exchange.name },\n },\n },\n async () => {\n const products = await exchange.listProducts();\n return { res: { code: 0, message: 'OK', data: products } };\n },\n );\n\n // GetPositions\n terminal.server.provideService<\n { credential: { type: string; payload: T }; product_id?: string },\n IPosition[]\n >(\n 'GetPositions',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n if (msg.req.product_id) {\n const positions = await exchange.getPositionsByProductId(\n msg.req.credential.payload,\n msg.req.product_id,\n );\n return { res: { code: 0, message: 'OK', data: positions } };\n }\n const positions = await exchange.getPositions(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: positions } };\n },\n );\n\n // GetOrders\n terminal.server.provideService<{ credential: { type: string; payload: T }; product_id?: string }, IOrder[]>(\n 'GetOrders',\n {\n type: 'object',\n required: ['credential'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n if (msg.req.product_id) {\n const orders = await exchange.getOrdersByProductId(msg.req.credential.payload, msg.req.product_id);\n return { res: { code: 0, message: 'OK', data: orders } };\n }\n const orders = await exchange.getOrders(msg.req.credential.payload);\n return { res: { code: 0, message: 'OK', data: orders } };\n },\n );\n\n // SubmitOrder\n terminal.server.provideService<\n { credential: { type: string; payload: T }; order: IOrder },\n { order_id: string }\n >(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n const result = await exchange.submitOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK', data: result } };\n },\n );\n\n // ModifyOrder\n terminal.server.provideService<{ credential: { type: string; payload: T }; order: IOrder }, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n await exchange.modifyOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK' } };\n },\n );\n\n // CancelOrder\n terminal.server.provideService<{ credential: { type: string; payload: T }; order: IOrder }, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['credential', 'order'],\n properties: {\n credential: makeCredentialSchema(type, credentialSchema),\n order: { type: 'object' },\n },\n },\n async (msg) => {\n await exchange.cancelOrder(msg.req.credential.payload, msg.req.order);\n return { res: { code: 0, message: 'OK' } };\n },\n );\n};\n\n/**\n * Get credential ID\n *\n * @public\n */\nexport const getCredentialId = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n): Promise<IResponse<string>> => {\n return terminal.client.requestForResponse('GetCredentialId', { credential });\n};\n\n/**\n * List products\n *\n * @public\n */\nexport const listProducts = async (terminal: Terminal, type: string): Promise<IResponse<IProduct[]>> => {\n return terminal.client.requestForResponse('ListProducts', { type });\n};\n\n/**\n * Get positions\n *\n * @public\n */\nexport const getPositions = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n product_id?: string,\n): Promise<IResponse<IPosition[]>> => {\n return terminal.client.requestForResponse('GetPositions', { credential, product_id });\n};\n\n/**\n * Get orders\n *\n * @public\n */\nexport const getOrders = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n product_id?: string,\n): Promise<IResponse<IOrder[]>> => {\n return terminal.client.requestForResponse('GetOrders', { credential, product_id });\n};\n\n/**\n * Submit order\n *\n * @public\n */\nexport const submitOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<{ order_id: string }>> => {\n return terminal.client.requestForResponse('SubmitOrder', { credential, order });\n};\n\n/**\n * Modify order\n *\n * @public\n */\nexport const modifyOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<void>> => {\n return terminal.client.requestForResponse('ModifyOrder', { credential, order });\n};\n\n/**\n * Cancel order\n *\n * @public\n */\nexport const cancelOrder = async <T>(\n terminal: Terminal,\n credential: { type: string; payload: T },\n order: IOrder,\n): Promise<IResponse<void>> => {\n return terminal.client.requestForResponse('CancelOrder', { credential, order });\n};\n"]}
@@ -0,0 +1,128 @@
1
+ import { createValidator } from '@yuants/protocol/lib/schema';
2
+ import { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';
3
+ import { encodePath } from '@yuants/utils';
4
+ import { newError } from '../../utils/lib';
5
+ const schemaValidator = createValidator({
6
+ type: 'object',
7
+ required: ['type', 'properties'],
8
+ properties: {
9
+ type: { type: 'string', const: 'object' },
10
+ required: { type: 'array', const: ['product_id', 'direction', 'time'] },
11
+ properties: {
12
+ type: 'object',
13
+ required: ['product_id', 'direction', 'time'],
14
+ properties: {
15
+ product_id: {
16
+ type: 'object',
17
+ required: ['type', 'pattern'],
18
+ properties: {
19
+ type: { type: 'string', const: 'string' },
20
+ pattern: { type: 'string', pattern: '^\\^' },
21
+ },
22
+ },
23
+ direction: {
24
+ type: 'object',
25
+ required: ['const'],
26
+ properties: {
27
+ const: { type: 'string', enum: ['backward', 'forward'] },
28
+ },
29
+ },
30
+ time: {
31
+ type: 'object',
32
+ required: ['type'],
33
+ properties: {
34
+ type: { type: 'string', const: 'number' },
35
+ },
36
+ },
37
+ },
38
+ },
39
+ },
40
+ });
41
+ /**
42
+ * @public
43
+ */
44
+ export const parseInterestRateServiceMetadataFromSchema = (schema) => {
45
+ if (!schema)
46
+ throw newError('INTEREST_RATE_SERVICE_SCHEMA_MISSING', { schema });
47
+ if (!schemaValidator(schema))
48
+ throw newError('INTEREST_RATE_SERVICE_SCHEMA_INVALID', { schema });
49
+ return {
50
+ product_id_prefix: schema.properties.product_id.pattern.slice(1),
51
+ direction: schema.properties.direction.const,
52
+ };
53
+ };
54
+ const INTEREST_RATE_INSERT_COLUMNS = [
55
+ 'series_id',
56
+ 'created_at',
57
+ 'datasource_id',
58
+ 'product_id',
59
+ 'long_rate',
60
+ 'short_rate',
61
+ 'settlement_price',
62
+ ];
63
+ const computeInterestRatePageRange = (items) => {
64
+ if (items.length === 0)
65
+ return undefined;
66
+ let start = items[0];
67
+ let startMs = Date.parse(start.created_at);
68
+ let end = items[0];
69
+ let endMs = Date.parse(end.created_at);
70
+ for (const item of items) {
71
+ const createdAtMs = Date.parse(item.created_at);
72
+ if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {
73
+ start = item;
74
+ startMs = createdAtMs;
75
+ }
76
+ if (!isNaN(createdAtMs) && (isNaN(endMs) || createdAtMs > endMs)) {
77
+ end = item;
78
+ endMs = createdAtMs;
79
+ }
80
+ }
81
+ return { start_time: start.created_at, end_time: end.created_at };
82
+ };
83
+ /**
84
+ * @public
85
+ */
86
+ export const provideInterestRateService = (terminal, metadata, fetchPage, serviceOptions) => {
87
+ return terminal.server.provideService('IngestInterestRate', {
88
+ type: 'object',
89
+ required: ['product_id', 'direction', 'time'],
90
+ properties: {
91
+ product_id: { type: 'string', pattern: `^${metadata.product_id_prefix}` },
92
+ direction: { const: metadata.direction },
93
+ time: { type: 'number' },
94
+ },
95
+ }, async (msg) => {
96
+ try {
97
+ const series_id = encodePath(msg.req.product_id);
98
+ const items = await fetchPage(Object.assign(Object.assign({}, msg.req), { series_id }));
99
+ const normalized = items.map((x) => (Object.assign(Object.assign({}, x), { series_id, datasource_id: '', product_id: msg.req.product_id })));
100
+ if (normalized.length > 0) {
101
+ await requestSQL(terminal, buildInsertManyIntoTableSQL(normalized, 'interest_rate', {
102
+ columns: INTEREST_RATE_INSERT_COLUMNS,
103
+ conflictKeys: ['series_id', 'created_at'],
104
+ }));
105
+ }
106
+ const range = computeInterestRatePageRange(normalized);
107
+ if (range) {
108
+ await requestSQL(terminal, buildInsertManyIntoTableSQL([
109
+ {
110
+ series_id,
111
+ table_name: 'interest_rate',
112
+ start_time: range.start_time,
113
+ end_time: range.end_time,
114
+ },
115
+ ], 'series_data_range', {
116
+ columns: ['series_id', 'table_name', 'start_time', 'end_time'],
117
+ ignoreConflict: true,
118
+ }));
119
+ }
120
+ return { res: { code: 0, message: 'OK', data: { wrote_count: normalized.length, range } } };
121
+ }
122
+ catch (error) {
123
+ const message = error instanceof Error ? error.message : `${error}`;
124
+ return { res: { code: 1, message } };
125
+ }
126
+ }, serviceOptions);
127
+ };
128
+ //# sourceMappingURL=interest_rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interest_rate.js","sourceRoot":"","sources":["../src/interest_rate.ts"],"names":[],"mappings":"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","sourcesContent":["import { IInterestRate } from '@yuants/data-interest-rate';\nimport { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { createValidator } from '@yuants/protocol/lib/schema';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\nimport { encodePath } from '@yuants/utils';\nimport { newError } from '../../utils/lib';\nimport { ISeriesIngestResult, SeriesFetchDirection } from './types';\n\n/**\n * Interest Rate Service Metadata\n * @public\n */\nexport interface IInterestRateServiceMetadata {\n product_id_prefix: string;\n direction: SeriesFetchDirection;\n}\n\n/**\n * Interest Rate Service Request from VEX to Vendor\n * @public\n */\nexport interface IIngestInterestRateRequest {\n product_id: string;\n direction: SeriesFetchDirection;\n time: number;\n}\n\nconst schemaValidator = createValidator({\n type: 'object',\n required: ['type', 'properties'],\n properties: {\n type: { type: 'string', const: 'object' },\n required: { type: 'array', const: ['product_id', 'direction', 'time'] },\n properties: {\n type: 'object',\n required: ['product_id', 'direction', 'time'],\n properties: {\n product_id: {\n type: 'object',\n required: ['type', 'pattern'],\n properties: {\n type: { type: 'string', const: 'string' },\n pattern: { type: 'string', pattern: '^\\\\^' },\n },\n },\n direction: {\n type: 'object',\n required: ['const'],\n properties: {\n const: { type: 'string', enum: ['backward', 'forward'] },\n },\n },\n time: {\n type: 'object',\n required: ['type'],\n properties: {\n type: { type: 'string', const: 'number' },\n },\n },\n },\n },\n },\n});\n\n/**\n * @public\n */\nexport const parseInterestRateServiceMetadataFromSchema = (schema: any): IInterestRateServiceMetadata => {\n if (!schema) throw newError('INTEREST_RATE_SERVICE_SCHEMA_MISSING', { schema });\n if (!schemaValidator(schema)) throw newError('INTEREST_RATE_SERVICE_SCHEMA_INVALID', { schema });\n return {\n product_id_prefix: schema.properties.product_id.pattern.slice(1),\n direction: schema.properties.direction.const,\n };\n};\n\nconst INTEREST_RATE_INSERT_COLUMNS: Array<keyof IInterestRate> = [\n 'series_id',\n 'created_at',\n 'datasource_id',\n 'product_id',\n 'long_rate',\n 'short_rate',\n 'settlement_price',\n];\n\nconst computeInterestRatePageRange = (\n items: IInterestRate[],\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\n/**\n * @public\n */\nexport const provideInterestRateService = (\n terminal: Terminal,\n metadata: IInterestRateServiceMetadata,\n fetchPage: (request: IIngestInterestRateRequest & { series_id: string }) => Promise<IInterestRate[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestInterestRateRequest, ISeriesIngestResult>(\n 'IngestInterestRate',\n {\n type: 'object',\n required: ['product_id', 'direction', 'time'],\n properties: {\n product_id: { type: 'string', pattern: `^${metadata.product_id_prefix}` },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n },\n },\n async (msg) => {\n try {\n const series_id = encodePath(msg.req.product_id);\n\n const items = await fetchPage({ ...msg.req, series_id });\n\n const normalized: IInterestRate[] = items.map((x) => ({\n ...x,\n series_id,\n datasource_id: '',\n product_id: msg.req.product_id,\n }));\n\n if (normalized.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(normalized, 'interest_rate', {\n columns: INTEREST_RATE_INSERT_COLUMNS,\n conflictKeys: ['series_id', 'created_at'],\n }),\n );\n }\n\n const range = computeInterestRatePageRange(normalized);\n if (range) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(\n [\n {\n series_id,\n table_name: 'interest_rate',\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 ),\n );\n }\n\n return { res: { code: 0, message: 'OK', data: { wrote_count: normalized.length, range } } };\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"]}
@@ -0,0 +1,24 @@
1
+ import { parseInterestRateServiceMetadataFromSchema } from './interest_rate';
2
+ describe('parseInterestRateServiceMetadataFromSchema', () => {
3
+ it('parses interest rate service schema', () => {
4
+ const schema = {
5
+ type: 'object',
6
+ required: ['product_id', 'direction', 'time'],
7
+ properties: {
8
+ product_id: { type: 'string', pattern: '^BINANCE/' },
9
+ direction: { const: 'forward' },
10
+ time: { type: 'number' },
11
+ },
12
+ };
13
+ const meta = parseInterestRateServiceMetadataFromSchema(schema);
14
+ expect(meta).toEqual({
15
+ product_id_prefix: 'BINANCE/',
16
+ direction: 'forward',
17
+ });
18
+ });
19
+ it('throws when schema missing/invalid', () => {
20
+ expect(() => parseInterestRateServiceMetadataFromSchema(undefined)).toThrow('INTEREST_RATE_SERVICE_SCHEMA_MISSING');
21
+ expect(() => parseInterestRateServiceMetadataFromSchema({})).toThrow('INTEREST_RATE_SERVICE_SCHEMA_INVALID');
22
+ });
23
+ });
24
+ //# sourceMappingURL=interest_rate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interest_rate.test.js","sourceRoot":"","sources":["../src/interest_rate.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0CAA0C,EAAE,MAAM,iBAAiB,CAAC;AAE7E,QAAQ,CAAC,4CAA4C,EAAE,GAAG,EAAE;IAC1D,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,CAAC;YAC7C,UAAU,EAAE;gBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE;gBACpD,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;gBAC/B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aACzB;SACF,CAAC;QAEF,MAAM,IAAI,GAAG,0CAA0C,CAAC,MAAM,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,iBAAiB,EAAE,UAAU;YAC7B,SAAS,EAAE,SAAS;SACrB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,GAAG,EAAE,CAAC,0CAA0C,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CACzE,sCAAsC,CACvC,CAAC;QACF,MAAM,CAAC,GAAG,EAAE,CAAC,0CAA0C,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAClE,sCAAsC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { parseInterestRateServiceMetadataFromSchema } from './interest_rate';\n\ndescribe('parseInterestRateServiceMetadataFromSchema', () => {\n it('parses interest rate service schema', () => {\n const schema = {\n type: 'object',\n required: ['product_id', 'direction', 'time'],\n properties: {\n product_id: { type: 'string', pattern: '^BINANCE/' },\n direction: { const: 'forward' },\n time: { type: 'number' },\n },\n };\n\n const meta = parseInterestRateServiceMetadataFromSchema(schema);\n expect(meta).toEqual({\n product_id_prefix: 'BINANCE/',\n direction: 'forward',\n });\n });\n\n it('throws when schema missing/invalid', () => {\n expect(() => parseInterestRateServiceMetadataFromSchema(undefined)).toThrow(\n 'INTEREST_RATE_SERVICE_SCHEMA_MISSING',\n );\n expect(() => parseInterestRateServiceMetadataFromSchema({})).toThrow(\n 'INTEREST_RATE_SERVICE_SCHEMA_INVALID',\n );\n });\n});\n"]}
package/dist/ohlc.js ADDED
@@ -0,0 +1,153 @@
1
+ import { createValidator } from '@yuants/protocol/lib/schema';
2
+ import { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';
3
+ import { encodePath, formatTime } from '@yuants/utils';
4
+ import { newError } from '../../utils/lib';
5
+ const schemaValidator = createValidator({
6
+ type: 'object',
7
+ required: ['type', 'properties'],
8
+ properties: {
9
+ type: { type: 'string', const: 'object' },
10
+ required: { type: 'array', const: ['product_id', 'duration', 'direction', 'time'] },
11
+ properties: {
12
+ type: 'object',
13
+ required: ['product_id', 'duration', 'direction', 'time'],
14
+ properties: {
15
+ product_id: {
16
+ type: 'object',
17
+ required: ['type', 'pattern'],
18
+ properties: {
19
+ type: { type: 'string', const: 'string' },
20
+ pattern: { type: 'string', pattern: '^\\^' },
21
+ },
22
+ },
23
+ duration: {
24
+ type: 'object',
25
+ required: ['type', 'enum'],
26
+ properties: {
27
+ type: { type: 'string', const: 'string' },
28
+ enum: { type: 'array', items: { type: 'string' } },
29
+ },
30
+ },
31
+ direction: {
32
+ type: 'object',
33
+ required: ['const'],
34
+ properties: {
35
+ const: { type: 'string', enum: ['backward', 'forward'] },
36
+ },
37
+ },
38
+ time: {
39
+ type: 'object',
40
+ required: ['type'],
41
+ properties: {
42
+ type: { type: 'string', const: 'number' },
43
+ },
44
+ },
45
+ },
46
+ },
47
+ },
48
+ });
49
+ /**
50
+ * @public
51
+ */
52
+ export const parseOHLCServiceMetadataFromSchema = (schema) => {
53
+ if (!schema)
54
+ throw newError('OHLC_SERVICE_SCHEMA_MISSING', { schema });
55
+ if (!schemaValidator(schema))
56
+ throw newError('OHLC_SERVICE_SCHEMA_INVALID', { schema });
57
+ return {
58
+ product_id_prefix: schema.properties.product_id.pattern.slice(1),
59
+ duration_list: schema.properties.duration.enum,
60
+ direction: schema.properties.direction.const,
61
+ };
62
+ };
63
+ const OHLC_INSERT_COLUMNS = [
64
+ 'series_id',
65
+ 'created_at',
66
+ 'datasource_id',
67
+ 'product_id',
68
+ 'duration',
69
+ 'closed_at',
70
+ 'open',
71
+ 'high',
72
+ 'low',
73
+ 'close',
74
+ 'volume',
75
+ 'open_interest',
76
+ ];
77
+ const computeOHLCPageRange = (items) => {
78
+ if (items.length === 0)
79
+ return undefined;
80
+ let start = items[0];
81
+ let startMs = Date.parse(start.created_at);
82
+ let end = items[0];
83
+ let endMs = Date.parse(end.closed_at) || Date.parse(end.created_at);
84
+ for (const item of items) {
85
+ const createdAtMs = Date.parse(item.created_at);
86
+ if (!isNaN(createdAtMs) && (isNaN(startMs) || createdAtMs < startMs)) {
87
+ start = item;
88
+ startMs = createdAtMs;
89
+ }
90
+ const closedAtMs = Date.parse(item.closed_at);
91
+ const candidateEndMs = !isNaN(closedAtMs) ? closedAtMs : createdAtMs;
92
+ if (!isNaN(candidateEndMs) && (isNaN(endMs) || candidateEndMs > endMs)) {
93
+ end = item;
94
+ endMs = candidateEndMs;
95
+ }
96
+ }
97
+ return {
98
+ start_time: start.created_at,
99
+ end_time: end.closed_at || end.created_at,
100
+ };
101
+ };
102
+ /**
103
+ * @public
104
+ */
105
+ export const provideOHLCService = (terminal, metadata, fetchPage, serviceOptions) => {
106
+ return terminal.server.provideService('IngestOHLC', {
107
+ type: 'object',
108
+ required: ['product_id', 'duration', 'direction', 'time'],
109
+ properties: {
110
+ product_id: { type: 'string', pattern: `^${metadata.product_id_prefix}` },
111
+ duration: { type: 'string', enum: metadata.duration_list },
112
+ direction: { const: metadata.direction },
113
+ time: { type: 'number' },
114
+ },
115
+ }, async (msg) => {
116
+ try {
117
+ const series_id = encodePath(msg.req.product_id, msg.req.duration);
118
+ const items = await fetchPage(Object.assign(Object.assign({}, msg.req), { series_id }));
119
+ console.info(formatTime(Date.now()), 'IngestOHLC', msg.req.product_id, msg.req.duration, 'fetched', items.length, 'bars');
120
+ const normalized = items.map((x) => {
121
+ var _a;
122
+ return (Object.assign(Object.assign({}, x), { series_id, datasource_id: '', product_id: msg.req.product_id, duration: msg.req.duration, open_interest: (_a = x.open_interest) !== null && _a !== void 0 ? _a : '0' }));
123
+ });
124
+ if (normalized.length > 0) {
125
+ await requestSQL(terminal, buildInsertManyIntoTableSQL(normalized, 'ohlc', {
126
+ columns: OHLC_INSERT_COLUMNS,
127
+ conflictKeys: ['series_id', 'created_at'],
128
+ }));
129
+ }
130
+ const range = computeOHLCPageRange(normalized);
131
+ if (range) {
132
+ await requestSQL(terminal, buildInsertManyIntoTableSQL([
133
+ {
134
+ series_id,
135
+ table_name: 'ohlc',
136
+ start_time: range.start_time,
137
+ end_time: range.end_time,
138
+ },
139
+ ], 'series_data_range', {
140
+ columns: ['series_id', 'table_name', 'start_time', 'end_time'],
141
+ ignoreConflict: true,
142
+ }));
143
+ }
144
+ return { res: { code: 0, message: 'OK', data: { wrote_count: normalized.length, range } } };
145
+ }
146
+ catch (error) {
147
+ const message = error instanceof Error ? error.message : `${error}`;
148
+ console.error(formatTime(Date.now()), 'IngestOHLC error:', error);
149
+ return { res: { code: 1, message } };
150
+ }
151
+ }, serviceOptions);
152
+ };
153
+ //# sourceMappingURL=ohlc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ohlc.js","sourceRoot":"","sources":["../src/ohlc.ts"],"names":[],"mappings":"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","sourcesContent":["import { IOHLC } from '@yuants/data-ohlc';\nimport { IServiceOptions, Terminal } from '@yuants/protocol';\nimport { createValidator } from '@yuants/protocol/lib/schema';\nimport { buildInsertManyIntoTableSQL, requestSQL } from '@yuants/sql';\nimport { encodePath, formatTime } from '@yuants/utils';\nimport { newError } from '../../utils/lib';\nimport { ISeriesIngestResult, SeriesFetchDirection } from './types';\n\n/**\n * OHLC Service Metadata\n * @public\n */\nexport interface IOHLCServiceMetadata {\n product_id_prefix: string;\n duration_list: string[];\n direction: SeriesFetchDirection;\n}\n\n/**\n * OHLC Service Request from VEX to Vendor\n * @public\n */\nexport interface IIngestOHLCRequest {\n product_id: string;\n duration: string;\n direction: SeriesFetchDirection;\n time: number;\n}\n\nconst schemaValidator = createValidator({\n type: 'object',\n required: ['type', 'properties'],\n properties: {\n type: { type: 'string', const: 'object' },\n required: { type: 'array', const: ['product_id', 'duration', 'direction', 'time'] },\n properties: {\n type: 'object',\n required: ['product_id', 'duration', 'direction', 'time'],\n properties: {\n product_id: {\n type: 'object',\n required: ['type', 'pattern'],\n properties: {\n type: { type: 'string', const: 'string' },\n pattern: { type: 'string', pattern: '^\\\\^' },\n },\n },\n duration: {\n type: 'object',\n required: ['type', 'enum'],\n properties: {\n type: { type: 'string', const: 'string' },\n enum: { type: 'array', items: { type: 'string' } },\n },\n },\n direction: {\n type: 'object',\n required: ['const'],\n properties: {\n const: { type: 'string', enum: ['backward', 'forward'] },\n },\n },\n time: {\n type: 'object',\n required: ['type'],\n properties: {\n type: { type: 'string', const: 'number' },\n },\n },\n },\n },\n },\n});\n\n/**\n * @public\n */\nexport const parseOHLCServiceMetadataFromSchema = (schema: any): IOHLCServiceMetadata => {\n if (!schema) throw newError('OHLC_SERVICE_SCHEMA_MISSING', { schema });\n if (!schemaValidator(schema)) throw newError('OHLC_SERVICE_SCHEMA_INVALID', { schema });\n return {\n product_id_prefix: schema.properties.product_id.pattern.slice(1),\n duration_list: schema.properties.duration.enum,\n direction: schema.properties.direction.const,\n };\n};\n\nconst OHLC_INSERT_COLUMNS: Array<keyof IOHLC> = [\n 'series_id',\n 'created_at',\n 'datasource_id',\n 'product_id',\n 'duration',\n 'closed_at',\n 'open',\n 'high',\n 'low',\n 'close',\n 'volume',\n 'open_interest',\n];\n\nconst computeOHLCPageRange = (items: IOHLC[]): { 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.closed_at) || 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 const closedAtMs = Date.parse(item.closed_at);\n const candidateEndMs = !isNaN(closedAtMs) ? closedAtMs : createdAtMs;\n if (!isNaN(candidateEndMs) && (isNaN(endMs) || candidateEndMs > endMs)) {\n end = item;\n endMs = candidateEndMs;\n }\n }\n\n return {\n start_time: start.created_at,\n end_time: end.closed_at || end.created_at,\n };\n};\n\n/**\n * @public\n */\nexport const provideOHLCService = (\n terminal: Terminal,\n metadata: IOHLCServiceMetadata,\n fetchPage: (request: IIngestOHLCRequest & { series_id: string }) => Promise<IOHLC[]>,\n serviceOptions?: IServiceOptions,\n) => {\n return terminal.server.provideService<IIngestOHLCRequest, ISeriesIngestResult>(\n 'IngestOHLC',\n {\n type: 'object',\n required: ['product_id', 'duration', 'direction', 'time'],\n properties: {\n product_id: { type: 'string', pattern: `^${metadata.product_id_prefix}` },\n duration: { type: 'string', enum: metadata.duration_list },\n direction: { const: metadata.direction },\n time: { type: 'number' },\n },\n },\n async (msg) => {\n try {\n const series_id = encodePath(msg.req.product_id, msg.req.duration);\n\n const items = await fetchPage({ ...msg.req, series_id });\n\n console.info(\n formatTime(Date.now()),\n 'IngestOHLC',\n msg.req.product_id,\n msg.req.duration,\n 'fetched',\n items.length,\n 'bars',\n );\n\n const normalized: IOHLC[] = items.map((x) => ({\n ...x,\n series_id,\n datasource_id: '',\n product_id: msg.req.product_id,\n duration: msg.req.duration,\n open_interest: x.open_interest ?? '0',\n }));\n\n if (normalized.length > 0) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(normalized, 'ohlc', {\n columns: OHLC_INSERT_COLUMNS,\n conflictKeys: ['series_id', 'created_at'],\n }),\n );\n }\n\n const range = computeOHLCPageRange(normalized);\n if (range) {\n await requestSQL(\n terminal,\n buildInsertManyIntoTableSQL(\n [\n {\n series_id,\n table_name: 'ohlc',\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 ),\n );\n }\n\n return { res: { code: 0, message: 'OK', data: { wrote_count: normalized.length, range } } };\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n console.error(formatTime(Date.now()), 'IngestOHLC error:', error);\n return { res: { code: 1, message } };\n }\n },\n serviceOptions,\n );\n};\n"]}
@@ -0,0 +1,26 @@
1
+ import { parseOHLCServiceMetadataFromSchema } from './ohlc';
2
+ describe('parseOHLCServiceMetadataFromSchema', () => {
3
+ it('parses OHLC service schema', () => {
4
+ const schema = {
5
+ type: 'object',
6
+ required: ['product_id', 'duration', 'direction', 'time'],
7
+ properties: {
8
+ product_id: { type: 'string', pattern: '^BINANCE/USDT-FUTURE' },
9
+ duration: { type: 'string', enum: ['PT1M', 'PT5M'] },
10
+ direction: { const: 'backward' },
11
+ time: { type: 'number' },
12
+ },
13
+ };
14
+ const meta = parseOHLCServiceMetadataFromSchema(schema);
15
+ expect(meta).toEqual({
16
+ product_id_prefix: 'BINANCE/USDT-FUTURE',
17
+ duration_list: ['PT1M', 'PT5M'],
18
+ direction: 'backward',
19
+ });
20
+ });
21
+ it('throws when schema missing/invalid', () => {
22
+ expect(() => parseOHLCServiceMetadataFromSchema(undefined)).toThrow('OHLC_SERVICE_SCHEMA_MISSING');
23
+ expect(() => parseOHLCServiceMetadataFromSchema({})).toThrow('OHLC_SERVICE_SCHEMA_INVALID');
24
+ });
25
+ });
26
+ //# sourceMappingURL=ohlc.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ohlc.test.js","sourceRoot":"","sources":["../src/ohlc.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,QAAQ,CAAC;AAE5D,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC;YACzD,UAAU,EAAE;gBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB,EAAE;gBAC/D,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;gBACpD,SAAS,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;gBAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aACzB;SACF,CAAC;QAEF,MAAM,IAAI,GAAG,kCAAkC,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,iBAAiB,EAAE,qBAAqB;YACxC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;YAC/B,SAAS,EAAE,UAAU;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,GAAG,EAAE,CAAC,kCAAkC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACnG,MAAM,CAAC,GAAG,EAAE,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { parseOHLCServiceMetadataFromSchema } from './ohlc';\n\ndescribe('parseOHLCServiceMetadataFromSchema', () => {\n it('parses OHLC service schema', () => {\n const schema = {\n type: 'object',\n required: ['product_id', 'duration', 'direction', 'time'],\n properties: {\n product_id: { type: 'string', pattern: '^BINANCE/USDT-FUTURE' },\n duration: { type: 'string', enum: ['PT1M', 'PT5M'] },\n direction: { const: 'backward' },\n time: { type: 'number' },\n },\n };\n\n const meta = parseOHLCServiceMetadataFromSchema(schema);\n expect(meta).toEqual({\n product_id_prefix: 'BINANCE/USDT-FUTURE',\n duration_list: ['PT1M', 'PT5M'],\n direction: 'backward',\n });\n });\n\n it('throws when schema missing/invalid', () => {\n expect(() => parseOHLCServiceMetadataFromSchema(undefined)).toThrow('OHLC_SERVICE_SCHEMA_MISSING');\n expect(() => parseOHLCServiceMetadataFromSchema({})).toThrow('OHLC_SERVICE_SCHEMA_INVALID');\n });\n});\n"]}
@@ -0,0 +1,31 @@
1
+ import { parseQuoteServiceMetadataFromSchema } from './quote';
2
+ describe('parseQuoteServiceMetadataFromSchema', () => {
3
+ it('parses quote service schema', () => {
4
+ const schema = {
5
+ type: 'object',
6
+ required: ['product_ids', 'fields'],
7
+ properties: {
8
+ product_ids: {
9
+ type: 'array',
10
+ maxItems: 20,
11
+ items: { type: 'string', pattern: '^BINANCE/USDT-FUTURE' },
12
+ },
13
+ fields: {
14
+ type: 'array',
15
+ const: ['last_price', 'bid_price'],
16
+ },
17
+ },
18
+ };
19
+ const meta = parseQuoteServiceMetadataFromSchema(schema);
20
+ expect(meta).toEqual({
21
+ product_id_prefix: 'BINANCE/USDT-FUTURE',
22
+ fields: ['last_price', 'bid_price'],
23
+ max_products_per_request: 20,
24
+ });
25
+ });
26
+ it('throws when schema missing/invalid', () => {
27
+ expect(() => parseQuoteServiceMetadataFromSchema(undefined)).toThrow('QUOTE_SERVICE_SCHEMA_MISSING');
28
+ expect(() => parseQuoteServiceMetadataFromSchema({})).toThrow('QUOTE_SERVICE_SCHEMA_INVALID');
29
+ });
30
+ });
31
+ //# sourceMappingURL=quote.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote.test.js","sourceRoot":"","sources":["../src/quote.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,SAAS,CAAC;AAE9D,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;YACnC,UAAU,EAAE;gBACV,WAAW,EAAE;oBACX,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,EAAE;oBACZ,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAsB,EAAE;iBAC3D;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC;iBACnC;aACF;SACF,CAAC;QAEF,MAAM,IAAI,GAAG,mCAAmC,CAAC,MAAM,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,iBAAiB,EAAE,qBAAqB;YACxC,MAAM,EAAE,CAAC,YAAY,EAAE,WAAW,CAAC;YACnC,wBAAwB,EAAE,EAAE;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,GAAG,EAAE,CAAC,mCAAmC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;QACrG,MAAM,CAAC,GAAG,EAAE,CAAC,mCAAmC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { parseQuoteServiceMetadataFromSchema } from './quote';\n\ndescribe('parseQuoteServiceMetadataFromSchema', () => {\n it('parses quote service schema', () => {\n const schema = {\n type: 'object',\n required: ['product_ids', 'fields'],\n properties: {\n product_ids: {\n type: 'array',\n maxItems: 20,\n items: { type: 'string', pattern: '^BINANCE/USDT-FUTURE' },\n },\n fields: {\n type: 'array',\n const: ['last_price', 'bid_price'],\n },\n },\n };\n\n const meta = parseQuoteServiceMetadataFromSchema(schema);\n expect(meta).toEqual({\n product_id_prefix: 'BINANCE/USDT-FUTURE',\n fields: ['last_price', 'bid_price'],\n max_products_per_request: 20,\n });\n });\n\n it('throws when schema missing/invalid', () => {\n expect(() => parseQuoteServiceMetadataFromSchema(undefined)).toThrow('QUOTE_SERVICE_SCHEMA_MISSING');\n expect(() => parseQuoteServiceMetadataFromSchema({})).toThrow('QUOTE_SERVICE_SCHEMA_INVALID');\n });\n});\n"]}