import { DerivativesTradingUsdsFuturesRestAPI } from '@binance/derivatives-trading-usds-futures' /** * 测试辅助工具类 */ export class TestHelpers { /** * 生成模拟的账户资产数据 */ static createMockAssets() { return [ { symbol: 'USDT', walletBalance: '1000.0', unrealizedPnl: '0.0', marginBalance: '1000.0', maintMargin: '0.0', initialMargin: '0.0', positionInitialMargin: '0.0', openOrderInitialMargin: '0.0', maxWithdrawAmount: '1000.0', crossWalletBalance: '1000.0', crossUnPnl: '0.0', availableBalance: '1000.0', marginAvailable: true, updateTime: 0, }, { symbol: 'BTC', walletBalance: '0.1', unrealizedPnl: '10.5', marginBalance: '10.6', maintMargin: '0.1', initialMargin: '0.1', positionInitialMargin: '0.1', openOrderInitialMargin: '0.0', maxWithdrawAmount: '10.5', crossWalletBalance: '0.1', crossUnPnl: '10.5', availableBalance: '10.5', marginAvailable: true, updateTime: 0, }, { symbol: 'ETH', walletBalance: '5.0', unrealizedPnl: '25.0', marginBalance: '30.0', maintMargin: '0.5', initialMargin: '0.5', positionInitialMargin: '0.5', openOrderInitialMargin: '0.0', maxWithdrawAmount: '29.5', crossWalletBalance: '5.0', crossUnPnl: '25.0', availableBalance: '29.5', marginAvailable: true, updateTime: 0, }, ] } /** * 生成模拟的持仓数据 */ static createMockPositions() { return [ { symbol: 'BTCUSDT', initialMargin: '0.1', maintMargin: '0.1', unrealizedPnl: '10.5', positionInitialMargin: '0.1', openOrderInitialMargin: '0.0', leverage: '10', isolated: false, entryPrice: '50000.0', maxNotional: '1000000', bidNotional: '0', askNotional: '0', positionSide: 'BOTH', positionAmt: '0.1', updateTime: 0, }, { symbol: 'ETHUSDT', initialMargin: '0.0', maintMargin: '0.0', unrealizedPnl: '0.0', positionInitialMargin: '0.0', openOrderInitialMargin: '0.0', leverage: '10', isolated: false, entryPrice: '0.0', maxNotional: '1000000', bidNotional: '0', askNotional: '0', positionSide: 'BOTH', positionAmt: '0.0', updateTime: 0, }, { symbol: 'ADAUSDT', initialMargin: '0.5', maintMargin: '0.5', unrealizedPnl: '-5.2', positionInitialMargin: '0.5', openOrderInitialMargin: '0.0', leverage: '10', isolated: false, entryPrice: '0.5', maxNotional: '1000000', bidNotional: '0', askNotional: '0', positionSide: 'BOTH', positionAmt: '-100.0', updateTime: 0, }, ] } /** * 生成模拟的订单数据 */ static createMockOrders() { return [ { orderId: 12345, symbol: 'BTCUSDT', status: 'NEW', clientOrderId: 'test_order_123', price: '50000', avgPrice: '0', origQty: '0.001', executedQty: '0', cumQuote: '0', timeInForce: 'GTC', type: 'LIMIT', reduceOnly: false, closePosition: false, side: 'BUY', positionSide: 'LONG', stopPrice: '0', workingType: 'CONTRACT_PRICE', priceProtect: false, origType: 'LIMIT', time: 1640995200000, updateTime: 1640995200000, }, { orderId: 12346, symbol: 'ETHUSDT', status: 'FILLED', clientOrderId: 'test_order_124', price: '3000', avgPrice: '3000', origQty: '0.01', executedQty: '0.01', cumQuote: '30', timeInForce: 'GTC', type: 'MARKET', reduceOnly: false, closePosition: false, side: 'BUY', positionSide: 'LONG', stopPrice: '0', workingType: 'CONTRACT_PRICE', priceProtect: false, origType: 'MARKET', time: 1640995200000, updateTime: 1640995200000, }, ] } /** * 生成模拟的成交数据 */ static createMockTrades() { return [ { id: 12365, symbol: 'BTCUSDT', orderId: 12345, pair: 'BTCUSDT', side: 'BUY', price: '50000', qty: '0.001', realizedPnl: '0', marginAsset: 'USDT', baseQty: '0.001', commission: '0.025', commissionAsset: 'USDT', time: 1640995200000, positionSide: 'LONG', maker: false, buyer: true, }, { id: 12366, symbol: 'ETHUSDT', orderId: 12346, pair: 'ETHUSDT', side: 'BUY', price: '3000', qty: '0.01', realizedPnl: '0', marginAsset: 'USDT', baseQty: '0.01', commission: '0.15', commissionAsset: 'USDT', time: 1640995200000, positionSide: 'LONG', maker: false, buyer: true, }, ] } /** * 生成模拟的订单结果 */ static createMockOrderResult(orderId: number = 12345, status: string = 'NEW') { return { orderId, symbol: 'BTCUSDT', status, clientOrderId: `test_order_${orderId}`, price: '50000', avgPrice: '0', origQty: '0.001', executedQty: '0', cumQuote: '0', timeInForce: 'GTC', type: 'LIMIT', reduceOnly: false, closePosition: false, side: 'BUY', positionSide: 'LONG', stopPrice: '0', workingType: 'CONTRACT_PRICE', priceProtect: false, origType: 'LIMIT', time: Date.now(), updateTime: Date.now(), } } /** * 生成模拟的 API 响应 */ static createMockApiResponse(data: any) { return { data: jest.fn().mockResolvedValue(data), } } /** * 生成模拟的 API 错误 */ static createMockApiError(message: string = 'API Error', code: number = -1000) { const error = new Error(message) as any error.code = code error.msg = message return error } /** * 验证订单参数 */ static validateOrderParams(params: any, expectedParams: any) { expect(params).toMatchObject(expectedParams) // 验证必需字段 expect(params).toHaveProperty('symbol') expect(params).toHaveProperty('side') expect(params).toHaveProperty('type') expect(params).toHaveProperty('timeInForce') expect(params).toHaveProperty('quantity') expect(params).toHaveProperty('price') } /** * 验证资产数据格式 */ static validateAssetData(asset: any) { expect(asset).toHaveProperty('symbol') expect(asset).toHaveProperty('walletBalance') expect(asset).toHaveProperty('unrealizedPnl') expect(asset).toHaveProperty('marginBalance') expect(asset).toHaveProperty('availableBalance') expect(typeof asset.symbol).toBe('string') expect(typeof asset.walletBalance).toBe('string') } /** * 验证持仓数据格式 */ static validatePositionData(position: any) { expect(position).toHaveProperty('symbol') expect(position).toHaveProperty('positionAmt') expect(position).toHaveProperty('unrealizedPnl') expect(position).toHaveProperty('entryPrice') expect(position).toHaveProperty('leverage') expect(typeof position.symbol).toBe('string') expect(typeof position.positionAmt).toBe('string') } /** * 验证订单数据格式 */ static validateOrderData(order: any) { expect(order).toHaveProperty('orderId') expect(order).toHaveProperty('symbol') expect(order).toHaveProperty('status') expect(order).toHaveProperty('side') expect(order).toHaveProperty('type') expect(typeof order.orderId).toBe('number') expect(typeof order.symbol).toBe('string') expect(typeof order.status).toBe('string') } /** * 验证成交数据格式 */ static validateTradeData(trade: any) { expect(trade).toHaveProperty('id') expect(trade).toHaveProperty('symbol') expect(trade).toHaveProperty('orderId') expect(trade).toHaveProperty('price') expect(trade).toHaveProperty('qty') expect(trade).toHaveProperty('side') expect(typeof trade.id).toBe('number') expect(typeof trade.symbol).toBe('string') expect(typeof trade.price).toBe('string') } /** * 生成测试用的交易对列表 */ static getTestSymbols() { return ['BTCUSDT', 'ETHUSDT', 'ADAUSDT', 'BNBUSDT', 'SOLUSDT'] } /** * 生成测试用的价格范围 */ static getTestPriceRange(symbol: string) { const priceRanges: { [key: string]: { min: number; max: number } } = { BTCUSDT: { min: 40000, max: 60000 }, ETHUSDT: { min: 2000, max: 4000 }, ADAUSDT: { min: 0.3, max: 0.7 }, BNBUSDT: { min: 200, max: 400 }, SOLUSDT: { min: 50, max: 150 }, } return priceRanges[symbol] || { min: 1, max: 100 } } /** * 生成测试用的数量范围 */ static getTestQuantityRange(symbol: string) { const quantityRanges: { [key: string]: { min: number; max: number } } = { BTCUSDT: { min: 0.001, max: 0.01 }, ETHUSDT: { min: 0.01, max: 0.1 }, ADAUSDT: { min: 10, max: 1000 }, BNBUSDT: { min: 0.1, max: 1 }, SOLUSDT: { min: 0.1, max: 10 }, } return quantityRanges[symbol] || { min: 0.001, max: 1 } } /** * 生成随机价格 */ static generateRandomPrice(symbol: string): number { const range = this.getTestPriceRange(symbol) return Math.random() * (range.max - range.min) + range.min } /** * 生成随机数量 */ static generateRandomQuantity(symbol: string): number { const range = this.getTestQuantityRange(symbol) return Math.random() * (range.max - range.min) + range.min } /** * 等待指定时间 */ static async wait(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)) } /** * 重试函数 */ static async retry(fn: () => Promise, maxAttempts: number = 3, delay: number = 1000): Promise { let lastError: Error for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await fn() } catch (error) { lastError = error as Error if (attempt < maxAttempts) { await this.wait(delay * attempt) } } } throw lastError! } }