test_order_execution_latency.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. "use strict";
  2. /**
  3. * Performance tests for order execution latency
  4. * Tests that order execution meets the <100ms requirement
  5. */
  6. Object.defineProperty(exports, "__esModule", { value: true });
  7. const HedgingManager_1 = require("../../src/core/HedgingManager");
  8. const OrderCoordinator_1 = require("../../src/core/OrderCoordinator");
  9. // Mock dependencies
  10. jest.mock('../../src/utils/Logger');
  11. jest.mock('../../src/core/RiskManager');
  12. jest.mock('../../src/core/HedgingStrategyEngine');
  13. jest.mock('../../src/core/HedgingConfigManager');
  14. jest.mock('../../src/core/OrderExecutor');
  15. describe('Order Execution Performance Tests', () => {
  16. let hedgingManager;
  17. let orderCoordinator;
  18. let orderExecutorAdapter;
  19. let mockConfig;
  20. beforeEach(() => {
  21. mockConfig = {
  22. maxConcurrentSessions: 10,
  23. sessionTimeout: 60000,
  24. riskCheckInterval: 1000
  25. };
  26. hedgingManager = new HedgingManager_1.HedgingManager(mockConfig);
  27. orderCoordinator = new OrderCoordinator_1.OrderCoordinator({
  28. maxConcurrentOrders: 20,
  29. orderTimeout: 30000,
  30. retryAttempts: 3,
  31. retryDelay: 1000
  32. });
  33. });
  34. afterEach(() => {
  35. jest.clearAllMocks();
  36. });
  37. describe('Order Execution Latency Tests', () => {
  38. beforeEach(async () => {
  39. await hedgingManager.initialize();
  40. await orderCoordinator.initialize();
  41. });
  42. it('should execute single order pair within 100ms', async () => {
  43. const hedgingOrder = {
  44. id: 'perf-test-order',
  45. sessionId: 'perf-test-session',
  46. strategyId: 'perf-test-strategy',
  47. orderPair: {
  48. buyOrder: {
  49. accountId: 'account1',
  50. side: 'buy',
  51. type: 'limit',
  52. size: 100,
  53. price: 2500
  54. },
  55. sellOrder: {
  56. accountId: 'account2',
  57. side: 'sell',
  58. type: 'limit',
  59. size: 100,
  60. price: 2500
  61. }
  62. },
  63. status: 'pending',
  64. fees: 0,
  65. slippage: 0,
  66. createdAt: new Date(),
  67. updatedAt: new Date()
  68. };
  69. const startTime = performance.now();
  70. const result = await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
  71. const endTime = performance.now();
  72. const executionTime = endTime - startTime;
  73. expect(executionTime).toBeLessThan(100); // Must be under 100ms
  74. expect(result).toBeDefined();
  75. expect(result.success).toBeDefined();
  76. console.log(`Single order pair execution time: ${executionTime.toFixed(2)}ms`);
  77. });
  78. it('should execute multiple order pairs concurrently within 100ms', async () => {
  79. const orders = [];
  80. // Create 5 concurrent orders
  81. for (let i = 0; i < 5; i++) {
  82. orders.push({
  83. id: `perf-concurrent-order-${i}`,
  84. sessionId: 'perf-concurrent-session',
  85. strategyId: 'perf-concurrent-strategy',
  86. orderPair: {
  87. buyOrder: {
  88. accountId: `account${i * 2 + 1}`,
  89. side: 'buy',
  90. type: 'limit',
  91. size: 100,
  92. price: 2500
  93. },
  94. sellOrder: {
  95. accountId: `account${i * 2 + 2}`,
  96. side: 'sell',
  97. type: 'limit',
  98. size: 100,
  99. price: 2500
  100. }
  101. },
  102. status: 'pending',
  103. fees: 0,
  104. slippage: 0,
  105. createdAt: new Date(),
  106. updatedAt: new Date()
  107. });
  108. }
  109. const startTime = performance.now();
  110. const results = await Promise.all(orders.map(order => orderCoordinator.executeHedgingOrderPair(order)));
  111. const endTime = performance.now();
  112. const executionTime = endTime - startTime;
  113. expect(executionTime).toBeLessThan(100); // Must be under 100ms
  114. expect(results).toHaveLength(5);
  115. results.forEach(result => {
  116. expect(result).toBeDefined();
  117. expect(result.success).toBeDefined();
  118. });
  119. console.log(`5 concurrent order pairs execution time: ${executionTime.toFixed(2)}ms`);
  120. });
  121. it('should execute 10 order pairs within 100ms', async () => {
  122. const orders = [];
  123. // Create 10 orders
  124. for (let i = 0; i < 10; i++) {
  125. orders.push({
  126. id: `perf-batch-order-${i}`,
  127. sessionId: 'perf-batch-session',
  128. strategyId: 'perf-batch-strategy',
  129. orderPair: {
  130. buyOrder: {
  131. accountId: `account${i * 2 + 1}`,
  132. side: 'buy',
  133. type: 'limit',
  134. size: 100,
  135. price: 2500
  136. },
  137. sellOrder: {
  138. accountId: `account${i * 2 + 2}`,
  139. side: 'sell',
  140. type: 'limit',
  141. size: 100,
  142. price: 2500
  143. }
  144. },
  145. status: 'pending',
  146. fees: 0,
  147. slippage: 0,
  148. createdAt: new Date(),
  149. updatedAt: new Date()
  150. });
  151. }
  152. const startTime = performance.now();
  153. const results = await Promise.all(orders.map(order => orderCoordinator.executeHedgingOrderPair(order)));
  154. const endTime = performance.now();
  155. const executionTime = endTime - startTime;
  156. expect(executionTime).toBeLessThan(100); // Must be under 100ms
  157. expect(results).toHaveLength(10);
  158. results.forEach(result => {
  159. expect(result).toBeDefined();
  160. expect(result.success).toBeDefined();
  161. });
  162. console.log(`10 order pairs execution time: ${executionTime.toFixed(2)}ms`);
  163. });
  164. it('should execute 20 order pairs within 100ms', async () => {
  165. const orders = [];
  166. // Create 20 orders
  167. for (let i = 0; i < 20; i++) {
  168. orders.push({
  169. id: `perf-stress-order-${i}`,
  170. sessionId: 'perf-stress-session',
  171. strategyId: 'perf-stress-strategy',
  172. orderPair: {
  173. buyOrder: {
  174. accountId: `account${i * 2 + 1}`,
  175. side: 'buy',
  176. type: 'limit',
  177. size: 100,
  178. price: 2500
  179. },
  180. sellOrder: {
  181. accountId: `account${i * 2 + 2}`,
  182. side: 'sell',
  183. type: 'limit',
  184. size: 100,
  185. price: 2500
  186. }
  187. },
  188. status: 'pending',
  189. fees: 0,
  190. slippage: 0,
  191. createdAt: new Date(),
  192. updatedAt: new Date()
  193. });
  194. }
  195. const startTime = performance.now();
  196. const results = await Promise.all(orders.map(order => orderCoordinator.executeHedgingOrderPair(order)));
  197. const endTime = performance.now();
  198. const executionTime = endTime - startTime;
  199. expect(executionTime).toBeLessThan(100); // Must be under 100ms
  200. expect(results).toHaveLength(20);
  201. results.forEach(result => {
  202. expect(result).toBeDefined();
  203. expect(result.success).toBeDefined();
  204. });
  205. console.log(`20 order pairs execution time: ${executionTime.toFixed(2)}ms`);
  206. });
  207. it('should maintain performance under high load', async () => {
  208. const orders = [];
  209. // Create 50 orders for high load test
  210. for (let i = 0; i < 50; i++) {
  211. orders.push({
  212. id: `perf-highload-order-${i}`,
  213. sessionId: 'perf-highload-session',
  214. strategyId: 'perf-highload-strategy',
  215. orderPair: {
  216. buyOrder: {
  217. accountId: `account${i * 2 + 1}`,
  218. side: 'buy',
  219. type: 'limit',
  220. size: 100,
  221. price: 2500
  222. },
  223. sellOrder: {
  224. accountId: `account${i * 2 + 2}`,
  225. side: 'sell',
  226. type: 'limit',
  227. size: 100,
  228. price: 2500
  229. }
  230. },
  231. status: 'pending',
  232. fees: 0,
  233. slippage: 0,
  234. createdAt: new Date(),
  235. updatedAt: new Date()
  236. });
  237. }
  238. const startTime = performance.now();
  239. const results = await Promise.all(orders.map(order => orderCoordinator.executeHedgingOrderPair(order)));
  240. const endTime = performance.now();
  241. const executionTime = endTime - startTime;
  242. // High load test - allow up to 200ms for 50 orders
  243. expect(executionTime).toBeLessThan(200);
  244. expect(results).toHaveLength(50);
  245. results.forEach(result => {
  246. expect(result).toBeDefined();
  247. expect(result.success).toBeDefined();
  248. });
  249. console.log(`50 order pairs (high load) execution time: ${executionTime.toFixed(2)}ms`);
  250. });
  251. });
  252. describe('Session Creation Performance Tests', () => {
  253. beforeEach(async () => {
  254. await hedgingManager.initialize();
  255. });
  256. it('should create session within 50ms', async () => {
  257. const sessionRequest = {
  258. strategy: {
  259. symbol: 'ETH/USD',
  260. volumeDistribution: 'equal',
  261. priceRange: { min: 0.001, max: 0.01 },
  262. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  263. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  264. orderTypes: { primary: 'limit', fallback: 'market' }
  265. },
  266. accounts: ['account1', 'account2'],
  267. duration: 300000
  268. };
  269. const startTime = performance.now();
  270. const session = await hedgingManager.createSession(sessionRequest);
  271. const endTime = performance.now();
  272. const creationTime = endTime - startTime;
  273. expect(creationTime).toBeLessThan(50); // Must be under 50ms
  274. expect(session).toBeDefined();
  275. expect(session.id).toBeDefined();
  276. console.log(`Session creation time: ${creationTime.toFixed(2)}ms`);
  277. });
  278. it('should create multiple sessions concurrently within 100ms', async () => {
  279. const sessionRequests = [];
  280. // Create 5 concurrent session requests
  281. for (let i = 0; i < 5; i++) {
  282. sessionRequests.push({
  283. strategy: {
  284. symbol: 'ETH/USD',
  285. volumeDistribution: 'equal',
  286. priceRange: { min: 0.001, max: 0.01 },
  287. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  288. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  289. orderTypes: { primary: 'limit', fallback: 'market' }
  290. },
  291. accounts: [`account${i * 2 + 1}`, `account${i * 2 + 2}`],
  292. duration: 300000
  293. });
  294. }
  295. const startTime = performance.now();
  296. const sessions = await Promise.all(sessionRequests.map(request => hedgingManager.createSession(request)));
  297. const endTime = performance.now();
  298. const creationTime = endTime - startTime;
  299. expect(creationTime).toBeLessThan(100); // Must be under 100ms
  300. expect(sessions).toHaveLength(5);
  301. sessions.forEach(session => {
  302. expect(session).toBeDefined();
  303. expect(session.id).toBeDefined();
  304. });
  305. console.log(`5 concurrent session creation time: ${creationTime.toFixed(2)}ms`);
  306. });
  307. });
  308. describe('Risk Assessment Performance Tests', () => {
  309. beforeEach(async () => {
  310. await hedgingManager.initialize();
  311. });
  312. it('should assess risk within 10ms', async () => {
  313. const sessionRequest = {
  314. strategy: {
  315. symbol: 'ETH/USD',
  316. volumeDistribution: 'equal',
  317. priceRange: { min: 0.001, max: 0.01 },
  318. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  319. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  320. orderTypes: { primary: 'limit', fallback: 'market' }
  321. },
  322. accounts: ['account1', 'account2'],
  323. duration: 300000
  324. };
  325. const session = await hedgingManager.createSession(sessionRequest);
  326. const startTime = performance.now();
  327. const riskStatus = hedgingManager.getSessionRiskStatus(session.id);
  328. const endTime = performance.now();
  329. const assessmentTime = endTime - startTime;
  330. expect(assessmentTime).toBeLessThan(10); // Must be under 10ms
  331. expect(riskStatus).toBeDefined();
  332. expect(riskStatus.overallRisk).toBeDefined();
  333. console.log(`Risk assessment time: ${assessmentTime.toFixed(2)}ms`);
  334. });
  335. it('should assess risk for multiple sessions within 50ms', async () => {
  336. const sessions = [];
  337. // Create 10 sessions
  338. for (let i = 0; i < 10; i++) {
  339. const sessionRequest = {
  340. strategy: {
  341. symbol: 'ETH/USD',
  342. volumeDistribution: 'equal',
  343. priceRange: { min: 0.001, max: 0.01 },
  344. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  345. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  346. orderTypes: { primary: 'limit', fallback: 'market' }
  347. },
  348. accounts: [`account${i * 2 + 1}`, `account${i * 2 + 2}`],
  349. duration: 300000
  350. };
  351. const session = await hedgingManager.createSession(sessionRequest);
  352. sessions.push(session);
  353. }
  354. const startTime = performance.now();
  355. const riskStatuses = await Promise.all(sessions.map(session => hedgingManager.getSessionRiskStatus(session.id)));
  356. const endTime = performance.now();
  357. const assessmentTime = endTime - startTime;
  358. expect(assessmentTime).toBeLessThan(50); // Must be under 50ms
  359. expect(riskStatuses).toHaveLength(10);
  360. riskStatuses.forEach(riskStatus => {
  361. expect(riskStatus).toBeDefined();
  362. expect(riskStatus.overallRisk).toBeDefined();
  363. });
  364. console.log(`10 concurrent risk assessments time: ${assessmentTime.toFixed(2)}ms`);
  365. });
  366. });
  367. describe('Memory Usage Performance Tests', () => {
  368. beforeEach(async () => {
  369. await hedgingManager.initialize();
  370. });
  371. it('should not exceed memory limits during high volume operations', async () => {
  372. const initialMemory = process.memoryUsage();
  373. // Create 100 sessions
  374. const sessions = [];
  375. for (let i = 0; i < 100; i++) {
  376. const sessionRequest = {
  377. strategy: {
  378. symbol: 'ETH/USD',
  379. volumeDistribution: 'equal',
  380. priceRange: { min: 0.001, max: 0.01 },
  381. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  382. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  383. orderTypes: { primary: 'limit', fallback: 'market' }
  384. },
  385. accounts: [`account${i * 2 + 1}`, `account${i * 2 + 2}`],
  386. duration: 300000
  387. };
  388. const session = await hedgingManager.createSession(sessionRequest);
  389. sessions.push(session);
  390. }
  391. const finalMemory = process.memoryUsage();
  392. const memoryIncrease = finalMemory.heapUsed - initialMemory.heapUsed;
  393. // Memory increase should be reasonable (less than 100MB)
  394. expect(memoryIncrease).toBeLessThan(100 * 1024 * 1024);
  395. console.log(`Memory increase for 100 sessions: ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`);
  396. });
  397. it('should clean up memory after session completion', async () => {
  398. const sessionRequest = {
  399. strategy: {
  400. symbol: 'ETH/USD',
  401. volumeDistribution: 'equal',
  402. priceRange: { min: 0.001, max: 0.01 },
  403. timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
  404. riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
  405. orderTypes: { primary: 'limit', fallback: 'market' }
  406. },
  407. accounts: ['account1', 'account2'],
  408. duration: 300000
  409. };
  410. const initialMemory = process.memoryUsage();
  411. const session = await hedgingManager.createSession(sessionRequest);
  412. await hedgingManager.startSession(session.id);
  413. await hedgingManager.stopSession(session.id);
  414. // Force garbage collection if available
  415. if (global.gc) {
  416. global.gc();
  417. }
  418. const finalMemory = process.memoryUsage();
  419. const memoryIncrease = finalMemory.heapUsed - initialMemory.heapUsed;
  420. // Memory increase should be minimal after cleanup
  421. expect(memoryIncrease).toBeLessThan(10 * 1024 * 1024); // Less than 10MB
  422. console.log(`Memory increase after session cleanup: ${(memoryIncrease / 1024 / 1024).toFixed(2)}MB`);
  423. });
  424. });
  425. describe('Throughput Performance Tests', () => {
  426. beforeEach(async () => {
  427. await hedgingManager.initialize();
  428. await orderCoordinator.initialize();
  429. });
  430. it('should handle 1000 orders per minute', async () => {
  431. const orders = [];
  432. // Create 1000 orders
  433. for (let i = 0; i < 1000; i++) {
  434. orders.push({
  435. id: `throughput-order-${i}`,
  436. sessionId: 'throughput-session',
  437. strategyId: 'throughput-strategy',
  438. orderPair: {
  439. buyOrder: {
  440. accountId: `account${i * 2 + 1}`,
  441. side: 'buy',
  442. type: 'limit',
  443. size: 100,
  444. price: 2500
  445. },
  446. sellOrder: {
  447. accountId: `account${i * 2 + 2}`,
  448. side: 'sell',
  449. type: 'limit',
  450. size: 100,
  451. price: 2500
  452. }
  453. },
  454. status: 'pending',
  455. fees: 0,
  456. slippage: 0,
  457. createdAt: new Date(),
  458. updatedAt: new Date()
  459. });
  460. }
  461. const startTime = performance.now();
  462. const results = await Promise.all(orders.map(order => orderCoordinator.executeHedgingOrderPair(order)));
  463. const endTime = performance.now();
  464. const totalTime = endTime - startTime;
  465. const ordersPerSecond = (1000 / totalTime) * 1000;
  466. const ordersPerMinute = ordersPerSecond * 60;
  467. expect(ordersPerMinute).toBeGreaterThan(1000); // Must handle 1000+ orders per minute
  468. expect(results).toHaveLength(1000);
  469. console.log(`Throughput: ${ordersPerMinute.toFixed(0)} orders per minute`);
  470. console.log(`Total time for 1000 orders: ${totalTime.toFixed(2)}ms`);
  471. });
  472. });
  473. });
  474. //# sourceMappingURL=test_order_execution_latency.js.map