123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694 |
- "use strict";
- /**
- * Unit tests for OrderCoordinator
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- const OrderCoordinator_1 = require("../../src/core/OrderCoordinator");
- // Mock dependencies
- jest.mock('../../src/utils/Logger');
- describe('OrderCoordinator', () => {
- let orderCoordinator;
- let mockConfig;
- beforeEach(() => {
- mockConfig = {
- maxConcurrentOrders: 10,
- orderTimeout: 30000,
- retryAttempts: 3,
- retryDelay: 1000
- };
- orderCoordinator = new OrderCoordinator_1.OrderCoordinator(mockConfig);
- });
- afterEach(() => {
- jest.clearAllMocks();
- });
- describe('Initialization', () => {
- it('should initialize with correct configuration', async () => {
- await orderCoordinator.initialize();
- const status = orderCoordinator.getStatus();
- expect(status.isRunning).toBe(false);
- expect(status.totalOrders).toBe(0);
- });
- it('should throw error if already initialized', async () => {
- await orderCoordinator.initialize();
- await expect(orderCoordinator.initialize()).rejects.toThrow('OrderCoordinator is already initialized');
- });
- });
- describe('Order Execution', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should execute hedging order pair', async () => {
- const hedgingOrder = {
- id: 'test-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const result = await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- expect(result).toBeDefined();
- expect(result.success).toBeDefined();
- expect(typeof result.success).toBe('boolean');
- });
- it('should handle order execution failure', async () => {
- const invalidOrder = {
- id: 'invalid-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: -100, // Invalid negative size
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const result = await orderCoordinator.executeHedgingOrderPair(invalidOrder);
- expect(result.success).toBe(false);
- expect(result.error).toBeDefined();
- });
- it('should execute orders with retry mechanism', async () => {
- const hedgingOrder = {
- id: 'retry-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- // Mock retry scenario
- jest.spyOn(orderCoordinator, 'executeOrderWithRetry')
- .mockResolvedValueOnce({ success: false, error: 'Network error' })
- .mockResolvedValueOnce({ success: true, orderId: 'order-123' });
- const result = await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- expect(result).toBeDefined();
- });
- });
- describe('Order Validation', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should validate order details', () => {
- const validOrder = {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- };
- const isValid = orderCoordinator.validateOrderDetails(validOrder);
- expect(isValid).toBe(true);
- });
- it('should reject invalid order details', () => {
- const invalidOrder = {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: -100, // Invalid negative size
- price: 2500
- };
- const isValid = orderCoordinator.validateOrderDetails(invalidOrder);
- expect(isValid).toBe(false);
- });
- it('should validate order pair', () => {
- const validOrderPair = {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- };
- const isValid = orderCoordinator.validateOrderPair(validOrderPair);
- expect(isValid).toBe(true);
- });
- it('should reject invalid order pair', () => {
- const invalidOrderPair = {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 50, // Different size
- price: 2500
- }
- };
- const isValid = orderCoordinator.validateOrderPair(invalidOrderPair);
- expect(isValid).toBe(false);
- });
- });
- describe('Order Tracking', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should track order execution', async () => {
- const hedgingOrder = {
- id: 'track-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- const trackedOrder = orderCoordinator.getOrder('track-order');
- expect(trackedOrder).toBeDefined();
- });
- it('should return null for non-existent order', () => {
- const order = orderCoordinator.getOrder('non-existent');
- expect(order).toBeNull();
- });
- it('should get all orders', async () => {
- const hedgingOrder1 = {
- id: 'order-1',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const hedgingOrder2 = {
- id: 'order-2',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder1);
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder2);
- const allOrders = orderCoordinator.getAllOrders();
- expect(allOrders).toHaveLength(2);
- });
- it('should get orders by session', async () => {
- const hedgingOrder = {
- id: 'session-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- const sessionOrders = orderCoordinator.getSessionOrders('test-session');
- expect(sessionOrders).toHaveLength(1);
- expect(sessionOrders[0].id).toBe('session-order');
- });
- });
- describe('Order Cancellation', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should cancel hedging order pair', async () => {
- const hedgingOrder = {
- id: 'cancel-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- const result = await orderCoordinator.cancelHedgingOrderPair(hedgingOrder);
- expect(result).toBeDefined();
- expect(result.success).toBeDefined();
- });
- it('should handle cancellation failure', async () => {
- const hedgingOrder = {
- id: 'cancel-fail-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- // Mock cancellation failure
- jest.spyOn(orderCoordinator, 'cancelOrder')
- .mockRejectedValue(new Error('Cancellation failed'));
- const result = await orderCoordinator.cancelHedgingOrderPair(hedgingOrder);
- expect(result.success).toBe(false);
- expect(result.error).toBeDefined();
- });
- });
- describe('Position Neutrality', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should ensure position neutrality', async () => {
- const hedgingOrder = {
- id: 'neutrality-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const result = await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- if (result.success) {
- const isNeutral = orderCoordinator.checkPositionNeutrality('test-session');
- expect(isNeutral).toBe(true);
- }
- });
- it('should detect position imbalance', async () => {
- const hedgingOrder = {
- id: 'imbalance-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 50, // Different size causing imbalance
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- const isNeutral = orderCoordinator.checkPositionNeutrality('test-session');
- expect(isNeutral).toBe(false);
- });
- });
- describe('Statistics and Monitoring', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should return correct status', () => {
- const status = orderCoordinator.getStatus();
- expect(status).toBeDefined();
- expect(typeof status.isRunning).toBe('boolean');
- expect(typeof status.totalOrders).toBe('number');
- expect(typeof status.pendingOrders).toBe('number');
- expect(typeof status.successfulOrders).toBe('number');
- expect(typeof status.failedOrders).toBe('number');
- });
- it('should return correct statistics', () => {
- const stats = orderCoordinator.getStatistics();
- expect(stats).toBeDefined();
- expect(typeof stats.totalOrders).toBe('number');
- expect(typeof stats.successfulOrders).toBe('number');
- expect(typeof stats.failedOrders).toBe('number');
- expect(typeof stats.successRate).toBe('number');
- expect(typeof stats.averageExecutionTime).toBe('number');
- expect(typeof stats.totalVolume).toBe('number');
- });
- it('should calculate success rate correctly', async () => {
- const hedgingOrder1 = {
- id: 'success-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const hedgingOrder2 = {
- id: 'fail-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: -100, // Invalid size
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder1);
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder2);
- const stats = orderCoordinator.getStatistics();
- expect(stats.successRate).toBe(0.5); // 1 out of 2 successful
- });
- });
- describe('Event Emission', () => {
- beforeEach(async () => {
- await orderCoordinator.initialize();
- });
- it('should emit order executed event', async () => {
- const hedgingOrder = {
- id: 'event-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const eventSpy = jest.fn();
- orderCoordinator.on('orderExecuted', eventSpy);
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- expect(eventSpy).toHaveBeenCalled();
- });
- it('should emit order failed event', async () => {
- const hedgingOrder = {
- id: 'fail-event-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: -100, // Invalid size
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const eventSpy = jest.fn();
- orderCoordinator.on('orderFailed', eventSpy);
- await orderCoordinator.executeHedgingOrderPair(hedgingOrder);
- expect(eventSpy).toHaveBeenCalled();
- });
- });
- describe('Error Handling', () => {
- it('should handle initialization errors gracefully', async () => {
- const invalidConfig = {
- maxConcurrentOrders: -1, // Invalid negative value
- orderTimeout: 30000,
- retryAttempts: 3,
- retryDelay: 1000
- };
- const invalidCoordinator = new OrderCoordinator_1.OrderCoordinator(invalidConfig);
- await expect(invalidCoordinator.initialize()).rejects.toThrow();
- });
- it('should handle order execution errors gracefully', async () => {
- await orderCoordinator.initialize();
- const invalidOrder = {
- id: 'error-order',
- sessionId: 'test-session',
- strategyId: 'test-strategy',
- orderPair: {
- buyOrder: {
- accountId: 'account1',
- side: 'buy',
- type: 'limit',
- size: 100,
- price: 2500
- },
- sellOrder: {
- accountId: 'account2',
- side: 'sell',
- type: 'limit',
- size: 100,
- price: 2500
- }
- },
- status: 'pending',
- fees: 0,
- slippage: 0,
- createdAt: new Date(),
- updatedAt: new Date()
- };
- // Mock execution error
- jest.spyOn(orderCoordinator, 'executeOrderWithRetry')
- .mockRejectedValue(new Error('Execution failed'));
- const result = await orderCoordinator.executeHedgingOrderPair(invalidOrder);
- expect(result.success).toBe(false);
- expect(result.error).toBeDefined();
- });
- });
- describe('Lifecycle Management', () => {
- it('should start and stop the coordinator', async () => {
- await orderCoordinator.initialize();
- await orderCoordinator.start();
- const status = orderCoordinator.getStatus();
- expect(status.isRunning).toBe(true);
- await orderCoordinator.stop();
- const stoppedStatus = orderCoordinator.getStatus();
- expect(stoppedStatus.isRunning).toBe(false);
- });
- it('should throw error when starting already running coordinator', async () => {
- await orderCoordinator.initialize();
- await orderCoordinator.start();
- await expect(orderCoordinator.start()).rejects.toThrow();
- });
- it('should throw error when stopping non-running coordinator', async () => {
- await orderCoordinator.initialize();
- await expect(orderCoordinator.stop()).rejects.toThrow();
- });
- });
- });
- //# sourceMappingURL=test_order_coordinator.js.map
|