diff --git a/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/rqdata_adapter.cpython-311.pyc b/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/rqdata_adapter.cpython-311.pyc index 79e68c7..7dc46c6 100644 Binary files a/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/rqdata_adapter.cpython-311.pyc and b/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/rqdata_adapter.cpython-311.pyc differ diff --git a/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/tqsdk_adapter.cpython-311.pyc b/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/tqsdk_adapter.cpython-311.pyc index 96af1a5..c51bdbf 100644 Binary files a/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/tqsdk_adapter.cpython-311.pyc and b/backend/service_implementation/qihuo_analyzer/data/api_adapters/__pycache__/tqsdk_adapter.cpython-311.pyc differ diff --git a/backend/service_implementation/qihuo_analyzer/data/api_adapters/rqdata_adapter.py b/backend/service_implementation/qihuo_analyzer/data/api_adapters/rqdata_adapter.py index eb964ab..ce7a68b 100644 --- a/backend/service_implementation/qihuo_analyzer/data/api_adapters/rqdata_adapter.py +++ b/backend/service_implementation/qihuo_analyzer/data/api_adapters/rqdata_adapter.py @@ -214,7 +214,7 @@ class RqDataAdapter(BaseDataAdapter): print(f"无法获取真实数据:{'API未连接' if not self.api_connected else 'RQData不可用'}") return None except Exception as e: - print(f"获取K线数据失败:{e}") + print(f"rqdata获取K线数据失败:{e}") # 不再自动返回模拟数据,返回None return None diff --git a/backend/service_implementation/qihuo_analyzer/data/api_adapters/tqsdk_adapter.py b/backend/service_implementation/qihuo_analyzer/data/api_adapters/tqsdk_adapter.py index 1babe7f..181ed51 100644 --- a/backend/service_implementation/qihuo_analyzer/data/api_adapters/tqsdk_adapter.py +++ b/backend/service_implementation/qihuo_analyzer/data/api_adapters/tqsdk_adapter.py @@ -192,7 +192,7 @@ class TqSdkAdapter(BaseDataAdapter): print(f"无法获取真实数据:{'API未连接' if not self.api else 'TQSDK不可用'}") return None except Exception as e: - print(f"获取K线数据失败:{e}") + print(f"tqsdk获取K线数据失败:{e}") # 不再自动返回模拟数据,返回None return None diff --git a/backend/service_implementation/service/app.py b/backend/service_implementation/service/app.py index 07a3001..6407599 100644 --- a/backend/service_implementation/service/app.py +++ b/backend/service_implementation/service/app.py @@ -39,7 +39,9 @@ def get_contracts(): exchange = request.args.get('exchange', '') symbol = request.args.get('symbol', '') + print("正在获取合约数据..., exchange:", exchange, "symbol:", symbol) contracts = data_fetcher.get_contracts(exchange=exchange, symbol=symbol) + print(f"获取到 {contracts} 合约") return jsonify({'status': 'success', 'data': contracts}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 diff --git a/backend/service_implementation/service/data/futures_analysis.db b/backend/service_implementation/service/data/futures_analysis.db index 357fc6b..b533c4c 100644 Binary files a/backend/service_implementation/service/data/futures_analysis.db and b/backend/service_implementation/service/data/futures_analysis.db differ diff --git a/backend/src/services/ServiceImplementationClient.ts b/backend/src/services/ServiceImplementationClient.ts index e40c8fa..1a27b2f 100644 --- a/backend/src/services/ServiceImplementationClient.ts +++ b/backend/src/services/ServiceImplementationClient.ts @@ -73,6 +73,7 @@ class ServiceImplementationClient { const params: Record = {}; if (exchange) params.exchange = exchange; if (symbol) params.symbol = symbol; + logger.info(`Getting contracts for exchange ${exchange} and symbol ${symbol}`); return this.get<{ status: string; data: any[] }>('/api/contracts', params); } diff --git a/backend/src/services/marketService.ts b/backend/src/services/marketService.ts index 2997097..d650e62 100644 --- a/backend/src/services/marketService.ts +++ b/backend/src/services/marketService.ts @@ -39,14 +39,14 @@ export const fetchMarketOverview = async () => { // 转换为数组 const contractList = Array.from(uniqueContracts.values()); - logger.log(`获取到 ${contractList.length} 个独特品种`); + logger.log(`获取到 ${contractList.length} 个独特品种,分别是: ${contractList.map(c => c.code).join(', ')}`); // 使用获取到的合约列表 const overview = []; for (const future of contractList) { try { // 构建合约符号(使用大写代码,因为 service_implementation API 期望大写) - const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`; + const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}03`; // 获取合约详情 logger.log(`获取合约${symbol}详情...`); @@ -131,104 +131,104 @@ export const fetchMarketOverview = async () => { // service_implementation API 失败,尝试使用其他数据源 } - // 获取数据源配置 - const dataSourceConfig = getDataSourceConfig(); - logger.log('获取数据源配置:', dataSourceConfig); - // 检查是否有可用的数据源 - const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled; - if (!hasAvailableDataSource) { - throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); - } + // // 获取数据源配置 + // const dataSourceConfig = getDataSourceConfig(); + // logger.log('获取数据源配置:', dataSourceConfig); + // // 检查是否有可用的数据源 + // const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled; + // if (!hasAvailableDataSource) { + // throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); + // } - // 尝试使用TQSDK数据源 - if (dataSourceConfig.tqsdk?.enabled) { - try { - const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); + // // 尝试使用TQSDK数据源 + // if (dataSourceConfig.tqsdk?.enabled) { + // try { + // const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); - // 使用用户指定的合约列表 - const overview = []; - for (const future of futuresList) { - try { - // 构建合约符号(使用小写代码,因为TQAPI期望小写) - const symbol = `${future.exchange}.${future.code.toLowerCase()}${new Date().getFullYear().toString().slice(-2)}05`; - // 获取合约详情和实时行情 - const tick = await dataSource.getTickData(symbol); + // // 使用用户指定的合约列表 + // const overview = []; + // for (const future of futuresList) { + // try { + // // 构建合约符号(使用小写代码,因为TQAPI期望小写) + // const symbol = `${future.exchange}.${future.code.toLowerCase()}${new Date().getFullYear().toString().slice(-2)}05`; + // // 获取合约详情和实时行情 + // const tick = await dataSource.getTickData(symbol); - overview.push({ - code: future.code, - name: future.name, - 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), // 模拟ATR - adx: Math.floor(Math.random() * 60) + 10, // 模拟ADX - adxStatus: (adx: number) => { - 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: 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)) - }, - overallView: ['观望', '中线', '多头排列', '空头排列', '震荡'][Math.floor(Math.random() * 5)], - aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近` - }); - } catch (error) { - logger.error(`获取合约${future.code}行情失败:`, error); - // 跳过获取失败的合约 - continue; - } - } + // overview.push({ + // code: future.code, + // name: future.name, + // 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), // 模拟ATR + // adx: Math.floor(Math.random() * 60) + 10, // 模拟ADX + // adxStatus: (adx: number) => { + // 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: 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)) + // }, + // overallView: ['观望', '中线', '多头排列', '空头排列', '震荡'][Math.floor(Math.random() * 5)], + // aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近` + // }); + // } catch (error) { + // logger.error(`获取合约${future.code}行情失败:`, error); + // // 跳过获取失败的合约 + // continue; + // } + // } - return overview; - } catch (error) { - logger.error('TQSDK数据源获取失败:', error); - // TQSDK数据源失败,尝试使用测试数据源 - if (dataSourceConfig.test?.enabled) { - logger.log('切换到测试数据源'); - // 启用了测试数据源,使用测试数据 - await new Promise(resolve => setTimeout(resolve, 300)); - return generateFuturesOverview(); - } else { - // 未启用测试数据源,返回友好的错误提示 - throw new Error('获取市场概览失败,所有数据源均不可用'); - } - } - } else if (dataSourceConfig.test?.enabled) { - // 直接使用测试数据源 - logger.log('使用测试数据源'); - await new Promise(resolve => setTimeout(resolve, 300)); - return generateFuturesOverview(); - } else { - // 无可用数据源 - throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); - } + // return overview; + // } catch (error) { + // logger.error('TQSDK数据源获取失败:', error); + // // TQSDK数据源失败,尝试使用测试数据源 + // if (dataSourceConfig.test?.enabled) { + // logger.log('切换到测试数据源'); + // // 启用了测试数据源,使用测试数据 + // await new Promise(resolve => setTimeout(resolve, 300)); + // return generateFuturesOverview(); + // } else { + // // 未启用测试数据源,返回友好的错误提示 + // throw new Error('获取市场概览失败,所有数据源均不可用'); + // } + // } + // } else if (dataSourceConfig.test?.enabled) { + // // 直接使用测试数据源 + // logger.log('使用测试数据源'); + // await new Promise(resolve => setTimeout(resolve, 300)); + // return generateFuturesOverview(); + // } else { + // // 无可用数据源 + // throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); + // } } catch (error) { logger.error('获取市场概览失败:', error); // 直接返回友好的错误提示 @@ -252,7 +252,7 @@ export const fetchMarketDetail = async (symbol: string) => { logger.log('尝试使用 service_implementation API 获取品种详情...'); // 构建合约符号(使用大写代码,因为 service_implementation API 期望大写) - const contractSymbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`; + const contractSymbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}03`; // 获取合约详情 logger.log(`获取合约${contractSymbol}详情...`); @@ -461,7 +461,7 @@ export const fetchKlineData = async (symbol: string, period: string) => { logger.log('尝试使用 service_implementation API 获取K线数据...'); // 构建合约符号(使用大写代码,因为 service_implementation API 期望大写) - const contractSymbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`; + const contractSymbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}3`; // 转换周期格式 let duration = period; @@ -517,57 +517,57 @@ export const fetchKlineData = async (symbol: string, period: string) => { // service_implementation API 失败,尝试使用其他数据源 } - // 获取数据源配置 - const dataSourceConfig = getDataSourceConfig(); + // // 获取数据源配置 + // const dataSourceConfig = getDataSourceConfig(); - // 检查是否有可用的数据源 - const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled; - if (!hasAvailableDataSource) { - throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); - } + // // 检查是否有可用的数据源 + // const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled; + // if (!hasAvailableDataSource) { + // throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); + // } - // 尝试使用TQSDK数据源 - if (dataSourceConfig.tqsdk?.enabled) { - try { - const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); + // // 尝试使用TQSDK数据源 + // if (dataSourceConfig.tqsdk?.enabled) { + // try { + // const dataSource = await DataSourceFactory.getDataSource(DataSourceType.TQSDK, dataSourceConfig); - // 构建合约符号(使用小写代码,因为TQAPI期望小写) - const contractSymbol = `${future.exchange}.${future.code.toLowerCase()}${new Date().getFullYear().toString().slice(-2)}05`; + // // 构建合约符号(使用小写代码,因为TQAPI期望小写) + // const contractSymbol = `${future.exchange}.${future.code.toLowerCase()}${new Date().getFullYear().toString().slice(-2)}05`; - // 获取K线数据 - const klineData = await dataSource.getKlineData(contractSymbol, period, 30); + // // 获取K线数据 + // const klineData = await dataSource.getKlineData(contractSymbol, 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) { - logger.error('TQSDK数据源获取失败:', error); - // TQSDK数据源失败,尝试使用测试数据源 - if (dataSourceConfig.test?.enabled) { - logger.log('切换到测试数据源'); - // 启用了测试数据源,使用测试数据 - await new Promise(resolve => setTimeout(resolve, 200)); - return generateKlineData(30); - } else { - // 未启用测试数据源,返回友好的错误提示 - throw new Error('获取K线数据失败,所有数据源均不可用'); - } - } - } else if (dataSourceConfig.test?.enabled) { - // 直接使用测试数据源 - logger.log('使用测试数据源'); - await new Promise(resolve => setTimeout(resolve, 200)); - return generateKlineData(30); - } else { - // 无可用数据源 - throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); - } + // // 转换为前端需要的格式 + // 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) { + // logger.error('TQSDK数据源获取失败:', error); + // // TQSDK数据源失败,尝试使用测试数据源 + // if (dataSourceConfig.test?.enabled) { + // logger.log('切换到测试数据源'); + // // 启用了测试数据源,使用测试数据 + // await new Promise(resolve => setTimeout(resolve, 200)); + // return generateKlineData(30); + // } else { + // // 未启用测试数据源,返回友好的错误提示 + // throw new Error('获取K线数据失败,所有数据源均不可用'); + // } + // } + // } else if (dataSourceConfig.test?.enabled) { + // // 直接使用测试数据源 + // logger.log('使用测试数据源'); + // await new Promise(resolve => setTimeout(resolve, 200)); + // return generateKlineData(30); + // } else { + // // 无可用数据源 + // throw new Error('无可用数据源,请在管理配置中启用至少一个数据源'); + // } } catch (error) { logger.error(`获取合约${symbol}K线数据失败:`, error); // 直接返回友好的错误提示 @@ -610,7 +610,7 @@ export const fetchMarketHotspots = async () => { for (const future of contractList) { try { // 构建合约符号(使用大写代码,因为 service_implementation API 期望大写) - const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`; + const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}03`; // 获取合约详情 logger.log(`获取合约${symbol}详情...`);