123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- #!/usr/bin/env tsx
- /**
- * Pacifica 市场数据管理器使用示例
- * 演示如何使用WebSocket获取实时价格和订单簿数据
- */
- import { MarketDataManager, MarketDataManagerConfig } from '../src/core/MarketDataManager';
- import { Logger } from '../src/utils/Logger';
- // 配置示例
- const config: MarketDataManagerConfig = {
- websocket: {
- url: 'wss://ws.pacifica.fi/ws', // 主网WebSocket地址
- reconnectInterval: 5000,
- heartbeatInterval: 30000,
- maxReconnectAttempts: 10
- },
- priceData: {
- symbols: ['BTC', 'ETH', 'SOL'], // 订阅的交易对
- updateInterval: 1000,
- maxDataAge: 10000
- },
- orderBook: {
- symbols: ['BTC', 'ETH', 'SOL'],
- aggregationLevels: [1], // 只使用聚合级别1,获取前5档
- updateInterval: 1000,
- maxDataAge: 10000
- },
- cleanupInterval: 60000,
- maxDataAge: 300000
- };
- async function runMarketDataExample() {
- const logger = Logger.getInstance();
- logger.info('🚀 启动Pacifica市场数据示例');
- // 创建市场数据管理器
- const marketDataManager = new MarketDataManager(config);
- // 设置事件监听器
- setupEventListeners(marketDataManager);
- try {
- // 启动市场数据管理器
- await marketDataManager.start();
- logger.info('✅ 市场数据管理器启动成功');
- // 等待数据更新
- await waitForData(marketDataManager);
- // 演示数据访问
- demonstrateDataAccess(marketDataManager);
- // 运行状态监控
- await runStatusMonitoring(marketDataManager);
- } catch (error) {
- logger.error(`❌ 市场数据示例运行失败: ${error}`, error as Error);
- } finally {
- // 停止市场数据管理器
- await marketDataManager.stop();
- logger.info('🛑 市场数据管理器已停止');
- }
- }
- /**
- * 设置事件监听器
- */
- function setupEventListeners(marketDataManager: MarketDataManager) {
- const logger = Logger.getInstance();
- // 连接事件
- marketDataManager.on('connected', () => {
- logger.info('🔗 WebSocket连接已建立');
- });
- marketDataManager.on('disconnected', (info) => {
- logger.warn(`🔌 WebSocket连接断开: ${JSON.stringify(info)}`);
- });
- marketDataManager.on('error', (error) => {
- logger.error(`❌ 市场数据管理器错误: ${error.message}`, error);
- });
- // 价格数据事件
- marketDataManager.on('priceUpdate', (data) => {
- logger.info(`💰 价格更新: ${data.symbol} = $${data.getMarkPrice().toFixed(2)}`);
- });
- marketDataManager.on('priceChange', (change) => {
- const direction = change.changePercentage > 0 ? '📈' : '📉';
- logger.info(`${direction} 价格变化: ${change.symbol} ${change.changePercentage.toFixed(2)}% (${change.previousPrice.toFixed(2)} → ${change.currentPrice.toFixed(2)})`);
- });
- // 订单簿数据事件
- marketDataManager.on('orderBookUpdate', (data) => {
- const bestBid = data.getBestBid();
- const bestAsk = data.getBestAsk();
- const spread = data.getSpread();
-
- if (bestBid && bestAsk && spread) {
- logger.info(`📊 订单簿更新: ${data.symbol} 买价=${bestBid.toFixed(2)} 卖价=${bestAsk.toFixed(2)} 价差=${spread.toFixed(2)}`);
- }
- });
- marketDataManager.on('spreadChange', (change) => {
- logger.info(`📊 价差变化: ${change.symbol} ${change.changePercentage.toFixed(2)}% (${change.previousSpread.toFixed(2)} → ${change.currentSpread.toFixed(2)})`);
- });
- // 批量更新事件
- marketDataManager.on('batchPriceUpdate', (data) => {
- logger.info(`📦 批量价格更新: ${data.length} 个交易对`);
- });
- }
- /**
- * 等待数据更新
- */
- async function waitForData(marketDataManager: MarketDataManager): Promise<void> {
- const logger = Logger.getInstance();
- logger.info('⏳ 等待市场数据更新...');
- return new Promise((resolve) => {
- let priceUpdates = 0;
- let orderBookUpdates = 0;
- const checkData = () => {
- if (priceUpdates >= 3 && orderBookUpdates >= 3) {
- logger.info('✅ 已收到足够的数据更新');
- resolve();
- }
- };
- marketDataManager.on('priceUpdate', () => {
- priceUpdates++;
- checkData();
- });
- marketDataManager.on('orderBookUpdate', () => {
- orderBookUpdates++;
- checkData();
- });
- // 超时处理
- setTimeout(() => {
- logger.warn('⏰ 等待数据超时,继续执行');
- resolve();
- }, 30000); // 30秒超时
- });
- }
- /**
- * 演示数据访问功能
- */
- function demonstrateDataAccess(marketDataManager: MarketDataManager) {
- const logger = Logger.getInstance();
- logger.info('📋 演示数据访问功能');
- const symbols = ['BTC', 'ETH', 'SOL'];
- symbols.forEach(symbol => {
- // 价格数据访问
- const price = marketDataManager.getLatestPrice(symbol);
- const oraclePrice = marketDataManager.getLatestOraclePrice(symbol);
- const fundingRate = marketDataManager.getFundingRate(symbol);
- const volume24h = marketDataManager.getVolume24h(symbol);
- if (price) {
- logger.info(`💰 ${symbol} 价格信息:`);
- logger.info(` 标记价格: $${price.toFixed(2)}`);
- if (oraclePrice) logger.info(` 预言机价格: $${oraclePrice.toFixed(2)}`);
- if (fundingRate) logger.info(` 资金费率: ${(fundingRate * 100).toFixed(4)}%`);
- if (volume24h) logger.info(` 24h交易量: ${volume24h.toLocaleString()}`);
- }
- // 订单簿数据访问
- const bestBid = marketDataManager.getBestBid(symbol);
- const bestAsk = marketDataManager.getBestAsk(symbol);
- const spread = marketDataManager.getSpread(symbol);
- const spreadPercentage = marketDataManager.getSpreadPercentage(symbol);
- if (bestBid && bestAsk) {
- logger.info(`📊 ${symbol} 订单簿信息:`);
- logger.info(` 最佳买价: $${bestBid.toFixed(2)}`);
- logger.info(` 最佳卖价: $${bestAsk.toFixed(2)}`);
- if (spread) logger.info(` 价差: $${spread.toFixed(2)}`);
- if (spreadPercentage) logger.info(` 价差百分比: ${spreadPercentage.toFixed(4)}%`);
- }
- // 市场深度信息
- const marketDepth = marketDataManager.getMarketDepth(symbol, 5);
- if (marketDepth) {
- logger.info(`📈 ${symbol} 市场深度 (前5档):`);
- logger.info(' 买单:');
- marketDepth.bids.forEach((bid, index) => {
- logger.info(` ${index + 1}. $${bid.price.toFixed(2)} (${bid.volume.toFixed(2)} 数量, ${bid.orders} 订单)`);
- });
- logger.info(' 卖单:');
- marketDepth.asks.forEach((ask, index) => {
- logger.info(` ${index + 1}. $${ask.price.toFixed(2)} (${ask.volume.toFixed(2)} 数量, ${ask.orders} 订单)`);
- });
- }
- // 数据新鲜度检查
- const isPriceFresh = marketDataManager.isPriceDataFresh(symbol);
- const isOrderBookFresh = marketDataManager.isOrderBookDataFresh(symbol);
- const priceAge = marketDataManager.getPriceDataAge(symbol);
- const orderBookAge = marketDataManager.getOrderBookDataAge(symbol);
- logger.info(`⏱️ ${symbol} 数据新鲜度:`);
- logger.info(` 价格数据: ${isPriceFresh ? '✅ 新鲜' : '❌ 过期'} (年龄: ${priceAge}ms)`);
- logger.info(` 订单簿数据: ${isOrderBookFresh ? '✅ 新鲜' : '❌ 过期'} (年龄: ${orderBookAge}ms)`);
- logger.info(''); // 空行分隔
- });
- }
- /**
- * 运行状态监控
- */
- async function runStatusMonitoring(marketDataManager: MarketDataManager): Promise<void> {
- const logger = Logger.getInstance();
- logger.info('📊 开始状态监控...');
- return new Promise((resolve) => {
- const monitoringInterval = setInterval(() => {
- // 获取状态信息
- const status = marketDataManager.getStatus();
- const statistics = marketDataManager.getStatistics();
- const healthCheck = marketDataManager.getHealthCheck();
- logger.info('📈 系统状态报告:');
- logger.info(` WebSocket连接: ${status.websocket.isConnected ? '✅ 已连接' : '❌ 断开'}`);
- logger.info(` 价格数据: ${status.priceData.dataCount} 个交易对`);
- logger.info(` 订单簿数据: ${status.orderBook.dataCount} 条记录`);
- logger.info(` 健康状态: ${healthCheck.status} (${healthCheck.issues.length} 个问题)`);
- if (healthCheck.issues.length > 0) {
- logger.warn(` 问题列表: ${healthCheck.issues.join(', ')}`);
- }
- logger.info('📊 统计信息:');
- logger.info(` 价格数据: ${statistics.priceData.freshDataCount}/${statistics.priceData.totalSymbols} 新鲜`);
- logger.info(` 订单簿数据: ${statistics.orderBook.freshDataCount}/${statistics.orderBook.totalDataRecords} 新鲜`);
- logger.info(` 平均数据年龄: ${statistics.priceData.averageAge.toFixed(0)}ms`);
- logger.info(''); // 空行分隔
- }, 10000); // 每10秒报告一次
- // 30秒后停止监控
- setTimeout(() => {
- clearInterval(monitoringInterval);
- logger.info('📊 状态监控结束');
- resolve();
- }, 30000);
- });
- }
- // 主函数
- async function main() {
- const args = process.argv.slice(2);
-
- if (args.length === 0) {
- // 运行完整示例
- await runMarketDataExample();
- } else if (args[0] === 'status') {
- // 只显示状态
- const marketDataManager = new MarketDataManager(config);
- await marketDataManager.start();
-
- setTimeout(async () => {
- const status = marketDataManager.getStatus();
- const healthCheck = marketDataManager.getHealthCheck();
-
- console.log('📊 市场数据管理器状态:');
- console.log(JSON.stringify({ status, healthCheck }, null, 2));
-
- await marketDataManager.stop();
- }, 5000);
- } else if (args[0] === 'test') {
- // 测试连接
- const marketDataManager = new MarketDataManager(config);
-
- marketDataManager.on('connected', () => {
- console.log('✅ WebSocket连接测试成功');
- marketDataManager.stop();
- });
-
- marketDataManager.on('error', (error) => {
- console.log('❌ WebSocket连接测试失败:', error.message);
- process.exit(1);
- });
-
- await marketDataManager.start();
- } else {
- console.log('使用方法:');
- console.log(' npx tsx examples/market-data-example.ts # 运行完整示例');
- console.log(' npx tsx examples/market-data-example.ts status # 显示状态');
- console.log(' npx tsx examples/market-data-example.ts test # 测试连接');
- }
- }
- // 运行主函数
- if (import.meta.url === `file://${process.argv[1]}`) {
- main().catch(console.error);
- }
- export { MarketDataManager, MarketDataManagerConfig };
|