123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603 |
- "use strict";
- /**
- * Unit tests for HedgingStrategyEngine
- */
- Object.defineProperty(exports, "__esModule", { value: true });
- const HedgingStrategyEngine_1 = require("../../src/core/HedgingStrategyEngine");
- // Mock dependencies
- jest.mock('../../src/utils/Logger');
- describe('HedgingStrategyEngine', () => {
- let strategyEngine;
- let mockConfig;
- beforeEach(() => {
- mockConfig = {
- maxConcurrentStrategies: 5,
- strategyTimeout: 60000,
- orderGenerationInterval: 5000
- };
- strategyEngine = new HedgingStrategyEngine_1.HedgingStrategyEngine(mockConfig);
- });
- afterEach(() => {
- jest.clearAllMocks();
- });
- describe('Initialization', () => {
- it('should initialize with correct configuration', async () => {
- await strategyEngine.initialize();
- const status = strategyEngine.getStatus();
- expect(status.isRunning).toBe(false);
- expect(status.totalStrategies).toBe(0);
- });
- it('should throw error if already initialized', async () => {
- await strategyEngine.initialize();
- await expect(strategyEngine.initialize()).rejects.toThrow('HedgingStrategyEngine is already initialized');
- });
- });
- describe('Strategy Management', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should add a hedging strategy', () => {
- const strategy = {
- id: 'test-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- strategyEngine.addStrategy(strategy);
- const retrievedStrategy = strategyEngine.getStrategy('test-strategy');
- expect(retrievedStrategy).toBeDefined();
- expect(retrievedStrategy?.id).toBe('test-strategy');
- });
- it('should remove a hedging strategy', () => {
- const strategy = {
- id: 'remove-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- strategyEngine.addStrategy(strategy);
- strategyEngine.removeStrategy('remove-strategy');
- const retrievedStrategy = strategyEngine.getStrategy('remove-strategy');
- expect(retrievedStrategy).toBeNull();
- });
- it('should update a hedging strategy', () => {
- const strategy = {
- id: 'update-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- strategyEngine.addStrategy(strategy);
- const updatedStrategy = {
- ...strategy,
- symbol: 'BTC/USD',
- updatedAt: new Date()
- };
- strategyEngine.updateStrategy(updatedStrategy);
- const retrievedStrategy = strategyEngine.getStrategy('update-strategy');
- expect(retrievedStrategy?.symbol).toBe('BTC/USD');
- });
- it('should get all strategies', () => {
- const strategy1 = {
- id: 'strategy-1',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const strategy2 = {
- id: 'strategy-2',
- symbol: 'BTC/USD',
- volumeDistribution: 'weighted',
- priceRange: { min: 0.002, max: 0.02 },
- timing: { minInterval: 60, maxInterval: 180, orderSize: { min: 200, max: 1000 } },
- riskLimits: { maxPositionSize: 0.15, stopLossThreshold: 0.08, maxSlippage: 0.03 },
- orderTypes: { primary: 'market', fallback: 'limit' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- strategyEngine.addStrategy(strategy1);
- strategyEngine.addStrategy(strategy2);
- const allStrategies = strategyEngine.getAllStrategies();
- expect(allStrategies).toHaveLength(2);
- expect(allStrategies.map(s => s.id)).toContain('strategy-1');
- expect(allStrategies.map(s => s.id)).toContain('strategy-2');
- });
- });
- describe('Order Generation', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should generate hedging orders', () => {
- const strategy = {
- id: 'order-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const orders = strategyEngine.generateHedgingOrders(strategy, accounts, currentPrice);
- expect(orders).toBeDefined();
- expect(Array.isArray(orders)).toBe(true);
- expect(orders.length).toBeGreaterThan(0);
- });
- it('should generate orders with correct structure', () => {
- const strategy = {
- id: 'structure-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const orders = strategyEngine.generateHedgingOrders(strategy, accounts, currentPrice);
- if (orders.length > 0) {
- const order = orders[0];
- expect(order.id).toBeDefined();
- expect(order.sessionId).toBeDefined();
- expect(order.strategyId).toBe('structure-strategy');
- expect(order.orderPair).toBeDefined();
- expect(order.orderPair.buyOrder).toBeDefined();
- expect(order.orderPair.sellOrder).toBeDefined();
- expect(order.status).toBe('pending');
- }
- });
- it('should respect volume distribution', () => {
- const strategy = {
- id: 'volume-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2', 'account3'];
- const currentPrice = 2500;
- const orders = strategyEngine.generateHedgingOrders(strategy, accounts, currentPrice);
- // With equal distribution, each account should get similar order sizes
- if (orders.length > 0) {
- const order = orders[0];
- const buySize = order.orderPair.buyOrder.size;
- const sellSize = order.orderPair.sellOrder.size;
- expect(buySize).toBe(sellSize); // Buy and sell should be equal for neutrality
- }
- });
- it('should respect price range', () => {
- const strategy = {
- id: 'price-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const orders = strategyEngine.generateHedgingOrders(strategy, accounts, currentPrice);
- if (orders.length > 0) {
- const order = orders[0];
- const buyPrice = order.orderPair.buyOrder.price;
- const sellPrice = order.orderPair.sellOrder.price;
- if (buyPrice && sellPrice) {
- const minPrice = currentPrice * (1 - strategy.priceRange.max);
- const maxPrice = currentPrice * (1 + strategy.priceRange.max);
- expect(buyPrice).toBeGreaterThanOrEqual(minPrice);
- expect(buyPrice).toBeLessThanOrEqual(maxPrice);
- expect(sellPrice).toBeGreaterThanOrEqual(minPrice);
- expect(sellPrice).toBeLessThanOrEqual(maxPrice);
- }
- }
- });
- it('should respect order size limits', () => {
- const strategy = {
- id: 'size-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const orders = strategyEngine.generateHedgingOrders(strategy, accounts, currentPrice);
- if (orders.length > 0) {
- const order = orders[0];
- const buySize = order.orderPair.buyOrder.size;
- const sellSize = order.orderPair.sellOrder.size;
- expect(buySize).toBeGreaterThanOrEqual(strategy.timing.orderSize.min);
- expect(buySize).toBeLessThanOrEqual(strategy.timing.orderSize.max);
- expect(sellSize).toBeGreaterThanOrEqual(strategy.timing.orderSize.min);
- expect(sellSize).toBeLessThanOrEqual(strategy.timing.orderSize.max);
- }
- });
- });
- describe('Strategy Execution', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should execute a hedging strategy', async () => {
- const strategy = {
- id: 'execute-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const result = await strategyEngine.executeStrategy(strategy, accounts, currentPrice);
- expect(result).toBeDefined();
- expect(result.success).toBeDefined();
- expect(typeof result.success).toBe('boolean');
- });
- it('should handle strategy execution failure', async () => {
- const invalidStrategy = {
- id: 'invalid-strategy',
- symbol: '', // Invalid empty symbol
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const result = await strategyEngine.executeStrategy(invalidStrategy, accounts, currentPrice);
- expect(result.success).toBe(false);
- expect(result.error).toBeDefined();
- });
- it('should execute strategy with retry mechanism', async () => {
- const strategy = {
- id: 'retry-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- // Mock retry scenario
- jest.spyOn(strategyEngine, 'executeStrategyWithRetry')
- .mockResolvedValueOnce({ success: false, error: 'Network error' })
- .mockResolvedValueOnce({ success: true, orders: [] });
- const result = await strategyEngine.executeStrategy(strategy, accounts, currentPrice);
- expect(result).toBeDefined();
- });
- });
- describe('Strategy Validation', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should validate hedging strategy', () => {
- const validStrategy = {
- id: 'valid-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const isValid = strategyEngine.validateStrategy(validStrategy);
- expect(isValid).toBe(true);
- });
- it('should reject invalid hedging strategy', () => {
- const invalidStrategy = {
- id: 'invalid-strategy',
- symbol: '', // Invalid empty symbol
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const isValid = strategyEngine.validateStrategy(invalidStrategy);
- expect(isValid).toBe(false);
- });
- it('should validate price range', () => {
- const strategy = {
- id: 'price-range-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const isValid = strategyEngine.validatePriceRange(strategy.priceRange);
- expect(isValid).toBe(true);
- });
- it('should reject invalid price range', () => {
- const invalidPriceRange = { min: 0.01, max: 0.001 }; // min > max
- const isValid = strategyEngine.validatePriceRange(invalidPriceRange);
- expect(isValid).toBe(false);
- });
- it('should validate timing configuration', () => {
- const strategy = {
- id: 'timing-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const isValid = strategyEngine.validateTimingConfig(strategy.timing);
- expect(isValid).toBe(true);
- });
- it('should reject invalid timing configuration', () => {
- const invalidTiming = { minInterval: 120, maxInterval: 30, orderSize: { min: 500, max: 100 } }; // min > max
- const isValid = strategyEngine.validateTimingConfig(invalidTiming);
- expect(isValid).toBe(false);
- });
- });
- describe('Market Adaptation', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should adapt strategy to market conditions', () => {
- const strategy = {
- id: 'adapt-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const marketConditions = {
- volatility: 0.08,
- volume: 1000000,
- spread: 0.001
- };
- const adaptedStrategy = strategyEngine.adaptStrategyToMarket(strategy, marketConditions);
- expect(adaptedStrategy).toBeDefined();
- expect(adaptedStrategy.id).toBe(strategy.id);
- });
- it('should adjust order size based on volatility', () => {
- const strategy = {
- id: 'volatility-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const highVolatilityConditions = {
- volatility: 0.15,
- volume: 1000000,
- spread: 0.001
- };
- const adaptedStrategy = strategyEngine.adaptStrategyToMarket(strategy, highVolatilityConditions);
- // High volatility should result in smaller order sizes
- expect(adaptedStrategy.timing.orderSize.max).toBeLessThanOrEqual(strategy.timing.orderSize.max);
- });
- it('should adjust price range based on spread', () => {
- const strategy = {
- id: 'spread-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const wideSpreadConditions = {
- volatility: 0.05,
- volume: 1000000,
- spread: 0.005
- };
- const adaptedStrategy = strategyEngine.adaptStrategyToMarket(strategy, wideSpreadConditions);
- // Wide spread should result in wider price range
- expect(adaptedStrategy.priceRange.max).toBeGreaterThanOrEqual(strategy.priceRange.max);
- });
- });
- describe('Statistics and Monitoring', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should return correct status', () => {
- const status = strategyEngine.getStatus();
- expect(status).toBeDefined();
- expect(typeof status.isRunning).toBe('boolean');
- expect(typeof status.totalStrategies).toBe('number');
- expect(typeof status.activeStrategies).toBe('number');
- });
- it('should return correct statistics', () => {
- const stats = strategyEngine.getStatistics();
- expect(stats).toBeDefined();
- expect(typeof stats.totalStrategies).toBe('number');
- 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');
- });
- it('should calculate success rate correctly', async () => {
- const strategy1 = {
- id: 'success-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const strategy2 = {
- id: 'fail-strategy',
- symbol: '', // Invalid symbol
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- await strategyEngine.executeStrategy(strategy1, accounts, currentPrice);
- await strategyEngine.executeStrategy(strategy2, accounts, currentPrice);
- const stats = strategyEngine.getStatistics();
- expect(stats.successRate).toBe(0.5); // 1 out of 2 successful
- });
- });
- describe('Event Emission', () => {
- beforeEach(async () => {
- await strategyEngine.initialize();
- });
- it('should emit strategy added event', () => {
- const strategy = {
- id: 'event-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const eventSpy = jest.fn();
- strategyEngine.on('strategyAdded', eventSpy);
- strategyEngine.addStrategy(strategy);
- expect(eventSpy).toHaveBeenCalledWith(strategy);
- });
- it('should emit strategy executed event', async () => {
- const strategy = {
- id: 'execute-event-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = ['account1', 'account2'];
- const currentPrice = 2500;
- const eventSpy = jest.fn();
- strategyEngine.on('strategyExecuted', eventSpy);
- await strategyEngine.executeStrategy(strategy, accounts, currentPrice);
- expect(eventSpy).toHaveBeenCalled();
- });
- });
- describe('Error Handling', () => {
- it('should handle initialization errors gracefully', async () => {
- const invalidConfig = {
- maxConcurrentStrategies: -1, // Invalid negative value
- strategyTimeout: 60000,
- orderGenerationInterval: 5000
- };
- const invalidEngine = new HedgingStrategyEngine_1.HedgingStrategyEngine(invalidConfig);
- await expect(invalidEngine.initialize()).rejects.toThrow();
- });
- it('should handle strategy execution errors gracefully', async () => {
- await strategyEngine.initialize();
- const invalidStrategy = {
- id: 'error-strategy',
- symbol: 'ETH/USD',
- volumeDistribution: 'equal',
- priceRange: { min: 0.001, max: 0.01 },
- timing: { minInterval: 30, maxInterval: 120, orderSize: { min: 100, max: 500 } },
- riskLimits: { maxPositionSize: 0.1, stopLossThreshold: 0.05, maxSlippage: 0.02 },
- orderTypes: { primary: 'limit', fallback: 'market' },
- createdAt: new Date(),
- updatedAt: new Date()
- };
- const accounts = []; // Empty accounts array
- const currentPrice = 2500;
- const result = await strategyEngine.executeStrategy(invalidStrategy, accounts, currentPrice);
- expect(result.success).toBe(false);
- expect(result.error).toBeDefined();
- });
- });
- describe('Lifecycle Management', () => {
- it('should start and stop the engine', async () => {
- await strategyEngine.initialize();
- await strategyEngine.start();
- const status = strategyEngine.getStatus();
- expect(status.isRunning).toBe(true);
- await strategyEngine.stop();
- const stoppedStatus = strategyEngine.getStatus();
- expect(stoppedStatus.isRunning).toBe(false);
- });
- it('should throw error when starting already running engine', async () => {
- await strategyEngine.initialize();
- await strategyEngine.start();
- await expect(strategyEngine.start()).rejects.toThrow();
- });
- it('should throw error when stopping non-running engine', async () => {
- await strategyEngine.initialize();
- await expect(strategyEngine.stop()).rejects.toThrow();
- });
- });
- });
- //# sourceMappingURL=test_hedging_strategy_engine.js.map
|