// 市场数据服务 import { DataSourceFactory, DataSourceType } from './datasource/DataSourceFactory'; import { futuresList, generateFuturesOverview, generateFutureData, generateKlineData, riskAlerts } from '../utils/mockData'; import { config } from '../config'; // 获取数据源配置 const getDataSourceConfig = () => { // 这里应该从配置文件或数据库中读取数据源配置 // 暂时返回默认配置 return { tqsdk: { enabled: true, apiKey: '', apiSecret: '', username: '', password: '', timeout: 30000, retries: 3, maxConnections: 5 } }; }; // 获取市场概览 export const fetchMarketOverview = async () => { try { // 获取数据源配置 const dataSourceConfig = getDataSourceConfig(); // 使用TQSDK数据源 const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); const overview = await dataSource.getMarketOverview(); // 转换为前端需要的格式 return overview.map(item => ({ code: item.symbol, name: item.name, currentPrice: item.price, changePercent: item.change_percent, winRate: Math.floor(Math.random() * 50) + 30, // 模拟胜率 atr: +(Math.random() * 5 + 0.5).toFixed(2), // 模拟ATR adx: Math.floor(Math.random() * 60) + 10, // 模拟ADX adxStatus: adx => { if (adx < 20) return '无趋势/震荡'; if (adx < 40) return '弱趋势'; return '强趋势'; }, trends: { '5MIN': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '30MIN': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '1HOUR': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '1DAY': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 } }, tradingAdvice: { entry: item.price, stopLoss: item.price * (1 - 0.02 * (Math.random() + 0.5)), target: item.price * (1 + 0.03 * (Math.random() + 0.5)), resistance: item.price * (1 + 0.05 * (Math.random() + 0.5)), support: item.price * (1 - 0.05 * (Math.random() + 0.5)) }, overallView: ['观望', '中线', '多头排列', '空头排列', '震荡'][Math.floor(Math.random() * 5)], aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近` })); } catch (error) { console.error('获取市场概览失败:', error); // 失败时使用模拟数据 await new Promise(resolve => setTimeout(resolve, 300)); return generateFuturesOverview(); } }; // 获取品种详情 export const fetchMarketDetail = async (symbol: string) => { try { // 获取数据源配置 const dataSourceConfig = getDataSourceConfig(); // 使用TQSDK数据源 const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); const contract = await dataSource.getContractDetail(symbol); const tick = await dataSource.getTickData(symbol); // 转换为前端需要的格式 return { code: contract.symbol, name: contract.name, fullName: `${contract.name}-${contract.symbol}605`, currentPrice: tick.last_price, changePercent: tick.price_change / tick.pre_close * 100, winRate: Math.floor(Math.random() * 50) + 30, atr: +(Math.random() * 5 + 0.5).toFixed(2), adx: Math.floor(Math.random() * 60) + 10, adxStatus: adx => { if (adx < 20) return '无趋势/震荡'; if (adx < 40) return '弱趋势'; return '强趋势'; }, trends: { '5MIN': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '30MIN': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '1HOUR': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 }, '1DAY': { direction: ['看多', '看空', '观望'][Math.floor(Math.random() * 3)], status: ['多头趋势', '空头趋势', '震荡'][Math.floor(Math.random() * 3)], rsi: Math.floor(Math.random() * 80) + 10 } }, indicators: { macd: ['金叉向上', '死叉向下', '走平'][Math.floor(Math.random() * 3)], rsi: `${Math.floor(Math.random() * 80) + 10}(中性)`, bollinger: ['触及上轨', '触及下轨', '中轨附近'][Math.floor(Math.random() * 3)], kdj: ['金叉向上', '死叉向下', '走平'][Math.floor(Math.random() * 3)] }, tradingAdvice: { entry: tick.last_price, stopLoss: tick.last_price * (1 - 0.02 * (Math.random() + 0.5)), target: tick.last_price * (1 + 0.03 * (Math.random() + 0.5)), resistance: tick.last_price * (1 + 0.05 * (Math.random() + 0.5)), support: tick.last_price * (1 - 0.05 * (Math.random() + 0.5)) }, riskLevel: ['低', '中等', '高'][Math.floor(Math.random() * 3)], volatility: ['低', '中等', '高'][Math.floor(Math.random() * 3)], overallView: ['观望', '中线', '多头排列', '空头排列', '震荡'][Math.floor(Math.random() * 5)], aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近` }; } catch (error) { console.error(`获取品种${symbol}详情失败:`, error); // 失败时使用模拟数据 await new Promise(resolve => setTimeout(resolve, 200)); const future = futuresList.find(item => item.code === symbol); if (!future) { throw new Error('品种不存在'); } return generateFutureData(symbol, future.name); } }; // 获取K线数据 export const fetchKlineData = async (symbol: string, period: string) => { try { // 获取数据源配置 const dataSourceConfig = getDataSourceConfig(); // 使用TQSDK数据源 const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); const klineData = await dataSource.getKlineData(symbol, period, 30); // 转换为前端需要的格式 return klineData.map(item => ({ timestamp: item.datetime / 1000000000, // 转换为秒 open: item.open, high: item.high, low: item.low, close: item.close, volume: item.volume })); } catch (error) { console.error(`获取合约${symbol}K线数据失败:`, error); // 失败时使用模拟数据 await new Promise(resolve => setTimeout(resolve, 200)); return generateKlineData(30); } }; // 获取市场热点 export const fetchMarketHotspots = async () => { try { // 使用TQSDK数据源 const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK); const overview = await dataSource.getMarketOverview(); // 按涨跌幅排序,返回前10个 return overview .sort((a, b) => Math.abs(b.change_percent) - Math.abs(a.change_percent)) .slice(0, 10) .map(item => ({ symbol: item.symbol, name: item.name, change: item.change_percent, volume: item.volume })); } catch (error) { console.error('获取市场热点失败:', error); // 失败时使用模拟数据 await new Promise(resolve => setTimeout(resolve, 200)); const overview = generateFuturesOverview(); // 按涨跌幅排序,返回前10个 return overview .sort((a, b) => Math.abs(b.changePercent) - Math.abs(a.changePercent)) .slice(0, 10) .map(item => ({ symbol: item.code, name: item.name, change: item.changePercent, volume: Math.floor(Math.random() * 1000000) + 100000 })); } }; // 获取风险预警 export const fetchRiskAlerts = async () => { // 直接返回模拟数据 await new Promise(resolve => setTimeout(resolve, 100)); return riskAlerts; };