| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- import { FutureConnector } from '../../src/exchanges/binance/FutureConnector'
- import { DerivativesTradingUsdsFuturesRestAPI } from '@binance/derivatives-trading-usds-futures'
- const describeBinanceIntegration = process.env.TEST_BINANCE === '1' ? describe : describe.skip
- // 集成测试 - 需要真实的 API 密钥
- // 这些测试会调用真实的 Binance API,请确保有有效的 API 密钥
- describeBinanceIntegration('FutureConnector Integration Tests', () => {
- let connector: FutureConnector
- beforeAll(() => {
- // 检查环境变量
- if (!process.env.API_KEY || !process.env.API_SECRET) {
- console.warn('⚠️ 跳过集成测试:API_KEY 或 API_SECRET 未设置')
- return
- }
- connector = new FutureConnector(process.env.API_KEY, process.env.API_SECRET)
- })
- // 跳过测试如果没有 API 密钥
- const testIfApiKey = process.env.API_KEY && process.env.API_SECRET ? test : test.skip
- describe('Account Information', () => {
- testIfApiKey(
- 'should get account assets info',
- async () => {
- const assets = await connector.getAssetsInfo()
- expect(Array.isArray(assets)).toBe(true)
- assets.forEach(asset => {
- expect(asset).toHaveProperty('symbol')
- expect(asset).toHaveProperty('walletBalance')
- expect(Number(asset.walletBalance)).toBeGreaterThan(0)
- })
- },
- 10000,
- )
- testIfApiKey(
- 'should get position info',
- async () => {
- const positions = await connector.getPositonInfo()
- expect(Array.isArray(positions)).toBe(true)
- positions.forEach(position => {
- expect(position).toHaveProperty('symbol')
- expect(position).toHaveProperty('positionAmt')
- expect(Number(position.positionAmt)).toBeGreaterThan(0)
- })
- },
- 10000,
- )
- testIfApiKey(
- 'should get all positions',
- async () => {
- const positions = await connector.getAllPositions()
- expect(Array.isArray(positions)).toBe(true)
- positions.forEach(position => {
- expect(position).toHaveProperty('symbol')
- expect(position).toHaveProperty('positionAmt')
- expect(position).toHaveProperty('unrealizedPnl')
- })
- },
- 10000,
- )
- testIfApiKey(
- 'should get position by symbol',
- async () => {
- const position = await connector.getPositionBalanceBySymbol('BTCUSDT')
- if (position) {
- expect(position).toHaveProperty('symbol', 'BTCUSDT')
- expect(position).toHaveProperty('positionAmt')
- expect(position).toHaveProperty('unrealizedPnl')
- } else {
- // 如果没有持仓,应该返回 null
- expect(position).toBeNull()
- }
- },
- 10000,
- )
- })
- describe('Order Management', () => {
- testIfApiKey(
- 'should get current open orders',
- async () => {
- await expect(connector.getCurrentAllOpenPosition()).resolves.not.toThrow()
- },
- 10000,
- )
- testIfApiKey(
- 'should get order history',
- async () => {
- const orders = await connector.getOrderHistory('BTCUSDT', undefined, undefined, 10)
- expect(Array.isArray(orders)).toBe(true)
- if (orders.length > 0) {
- orders.forEach(order => {
- expect(order).toHaveProperty('symbol', 'BTCUSDT')
- expect(order).toHaveProperty('orderId')
- expect(order).toHaveProperty('status')
- })
- }
- },
- 10000,
- )
- testIfApiKey(
- 'should get trade history',
- async () => {
- const trades = await connector.getTradeHistory('BTCUSDT', undefined, undefined, 10)
- expect(Array.isArray(trades)).toBe(true)
- if (trades.length > 0) {
- trades.forEach(trade => {
- expect(trade).toHaveProperty('symbol', 'BTCUSDT')
- expect(trade).toHaveProperty('id')
- expect(trade).toHaveProperty('price')
- expect(trade).toHaveProperty('qty')
- })
- }
- },
- 10000,
- )
- })
- describe('Trading Operations', () => {
- // 注意:这些测试会创建真实的订单,请谨慎使用
- // 建议在测试环境中使用小额订单
- testIfApiKey.skip(
- 'should place and cancel limit order',
- async () => {
- // 创建限价单
- const orderResult = await connector.openLimitOrder(
- 'BTCUSDT',
- 'long',
- 0.001, // 最小数量
- 40000, // 远低于市价的价格,确保不会成交
- 'GTC',
- )
- expect(orderResult).toBeDefined()
- expect(orderResult).toHaveProperty('orderId')
- expect(orderResult).toHaveProperty('status')
- // 撤销订单
- if (orderResult && orderResult.orderId) {
- const cancelResult = await connector.cancelOrder('BTCUSDT', orderResult.orderId)
- expect(cancelResult).toBeDefined()
- }
- },
- 30000,
- )
- testIfApiKey.skip(
- 'should place market order',
- async () => {
- // 市价单会立即成交,请谨慎使用
- const orderResult = await connector.openMarketOrder(
- 'BTCUSDT',
- 'long',
- 0.001, // 最小数量
- )
- expect(orderResult).toBeDefined()
- expect(orderResult).toHaveProperty('orderId')
- expect(orderResult).toHaveProperty('status')
- },
- 30000,
- )
- testIfApiKey.skip(
- 'should place stop order',
- async () => {
- // 止损单,设置远低于市价的价格
- const orderResult = await connector.openStopOrder(
- 'BTCUSDT',
- 'long',
- 0.001,
- 30000, // 远低于市价的止损价格
- 'STOP_MARKET',
- )
- expect(orderResult).toBeDefined()
- expect(orderResult).toHaveProperty('orderId')
- expect(orderResult).toHaveProperty('status')
- // 撤销订单
- if (orderResult && orderResult.orderId) {
- const cancelResult = await connector.cancelOrder('BTCUSDT', orderResult.orderId)
- expect(cancelResult).toBeDefined()
- }
- },
- 30000,
- )
- })
- describe('Account Settings', () => {
- testIfApiKey.skip(
- 'should set leverage',
- async () => {
- const result = await connector.setLeverage('BTCUSDT', 10)
- expect(result).toBeDefined()
- expect(result).toHaveProperty('leverage')
- expect(result).toHaveProperty('maxNotionalValue')
- },
- 10000,
- )
- testIfApiKey.skip(
- 'should set margin type',
- async () => {
- const result = await connector.setMarginType(
- 'BTCUSDT',
- DerivativesTradingUsdsFuturesRestAPI.ChangeMarginTypeMarginTypeEnum.ISOLATED,
- )
- expect(result).toBeDefined()
- expect(result).toHaveProperty('code')
- },
- 10000,
- )
- })
- describe('Error Handling', () => {
- testIfApiKey(
- 'should handle invalid symbol gracefully',
- async () => {
- const position = await connector.getPositionBalanceBySymbol('INVALID_SYMBOL')
- expect(position).toBeNull()
- },
- 10000,
- )
- testIfApiKey(
- 'should handle invalid order parameters',
- async () => {
- // 测试无效的订单参数
- const result = await connector.openPosition(
- 'INVALID_SYMBOL',
- DerivativesTradingUsdsFuturesRestAPI.NewOrderSideEnum.BUY,
- 0,
- 0,
- )
- // 应该返回 null 或抛出错误
- expect(result).toBeNull()
- },
- 10000,
- )
- })
- })
|