|
|
|
@ -3,6 +3,7 @@ import { DataSourceFactory, DataSourceType } from './datasource/DataSourceFactor
|
|
|
|
import { futuresList, generateFuturesOverview, generateFutureData, generateKlineData, riskAlerts } from '../utils/mockData';
|
|
|
|
import { futuresList, generateFuturesOverview, generateFutureData, generateKlineData, riskAlerts } from '../utils/mockData';
|
|
|
|
import { config } from '../config';
|
|
|
|
import { config } from '../config';
|
|
|
|
import { serviceImplementationClient } from './ServiceImplementationClient';
|
|
|
|
import { serviceImplementationClient } from './ServiceImplementationClient';
|
|
|
|
|
|
|
|
import { logger } from '../utils/logger';
|
|
|
|
|
|
|
|
|
|
|
|
// 获取数据源配置
|
|
|
|
// 获取数据源配置
|
|
|
|
const getDataSourceConfig = () => {
|
|
|
|
const getDataSourceConfig = () => {
|
|
|
|
@ -15,10 +16,10 @@ export const fetchMarketOverview = async () => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
console.log('尝试使用 service_implementation API 获取市场概览...');
|
|
|
|
logger.log('尝试使用 service_implementation API 获取市场概览...');
|
|
|
|
|
|
|
|
|
|
|
|
// 先获取合约列表
|
|
|
|
// 先获取合约列表
|
|
|
|
console.log('获取合约列表...');
|
|
|
|
logger.log('获取合约列表...');
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts();
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts();
|
|
|
|
const allContracts = contractsResponse.data;
|
|
|
|
const allContracts = contractsResponse.data;
|
|
|
|
|
|
|
|
|
|
|
|
@ -38,7 +39,7 @@ export const fetchMarketOverview = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为数组
|
|
|
|
// 转换为数组
|
|
|
|
const contractList = Array.from(uniqueContracts.values());
|
|
|
|
const contractList = Array.from(uniqueContracts.values());
|
|
|
|
console.log(`获取到 ${contractList.length} 个独特品种`);
|
|
|
|
logger.log(`获取到 ${contractList.length} 个独特品种`);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用获取到的合约列表
|
|
|
|
// 使用获取到的合约列表
|
|
|
|
const overview = [];
|
|
|
|
const overview = [];
|
|
|
|
@ -48,19 +49,24 @@ export const fetchMarketOverview = async () => {
|
|
|
|
const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`;
|
|
|
|
const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取合约详情
|
|
|
|
// 获取合约详情
|
|
|
|
console.log(`获取合约${symbol}详情...`);
|
|
|
|
logger.log(`获取合约${symbol}详情...`);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === symbol);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === symbol);
|
|
|
|
|
|
|
|
|
|
|
|
if (!contract) {
|
|
|
|
if (!contract) {
|
|
|
|
console.warn(`合约${symbol}不存在,跳过`);
|
|
|
|
logger.warn(`合约${symbol}不存在,跳过`);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新未来合约的中文名称
|
|
|
|
|
|
|
|
future.name = `${contract.product_name || future.name}`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取分析数据
|
|
|
|
// 获取分析数据
|
|
|
|
console.log(`分析合约${symbol}...`);
|
|
|
|
logger.log(`分析合约${symbol}...`);
|
|
|
|
|
|
|
|
logger.log(`before analyzeMarket: symbol=${symbol},time=${new Date().toISOString()}`);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(symbol);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(symbol);
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
|
|
|
|
logger.log(`after analyzeMarket: symbol=${symbol}, analysis=${JSON.stringify(analysis)}, time=${new Date().toISOString()}`);
|
|
|
|
|
|
|
|
|
|
|
|
overview.push({
|
|
|
|
overview.push({
|
|
|
|
code: future.code,
|
|
|
|
code: future.code,
|
|
|
|
@ -108,26 +114,26 @@ export const fetchMarketOverview = async () => {
|
|
|
|
aiAnalysis: `趋势:${analysis.trend || '中性'} | 概率:${analysis.probability ? Math.round(analysis.probability * 100) : 50}% | 方向:${analysis.direction || '观望'}`
|
|
|
|
aiAnalysis: `趋势:${analysis.trend || '中性'} | 概率:${analysis.probability ? Math.round(analysis.probability * 100) : 50}% | 方向:${analysis.direction || '观望'}`
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
logger.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (overview.length > 0) {
|
|
|
|
if (overview.length > 0) {
|
|
|
|
console.log('使用 service_implementation API 获取市场概览成功');
|
|
|
|
logger.log('使用 service_implementation API 获取市场概览成功');
|
|
|
|
return overview;
|
|
|
|
return overview;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.warn('service_implementation API 未返回数据,尝试使用其他数据源');
|
|
|
|
logger.warn('service_implementation API 未返回数据,尝试使用其他数据源');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('service_implementation API 获取失败:', error);
|
|
|
|
logger.error('service_implementation API 获取失败:', error);
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取数据源配置
|
|
|
|
// 获取数据源配置
|
|
|
|
const dataSourceConfig = getDataSourceConfig();
|
|
|
|
const dataSourceConfig = getDataSourceConfig();
|
|
|
|
console.log('获取数据源配置:', dataSourceConfig);
|
|
|
|
logger.log('获取数据源配置:', dataSourceConfig);
|
|
|
|
// 检查是否有可用的数据源
|
|
|
|
// 检查是否有可用的数据源
|
|
|
|
const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled;
|
|
|
|
const hasAvailableDataSource = dataSourceConfig.tqsdk?.enabled || dataSourceConfig.test?.enabled;
|
|
|
|
if (!hasAvailableDataSource) {
|
|
|
|
if (!hasAvailableDataSource) {
|
|
|
|
@ -194,7 +200,7 @@ export const fetchMarketOverview = async () => {
|
|
|
|
aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近`
|
|
|
|
aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近`
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
logger.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -202,10 +208,10 @@ export const fetchMarketOverview = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
return overview;
|
|
|
|
return overview;
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('TQSDK数据源获取失败:', error);
|
|
|
|
logger.error('TQSDK数据源获取失败:', error);
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
console.log('切换到测试数据源');
|
|
|
|
logger.log('切换到测试数据源');
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
|
|
return generateFuturesOverview();
|
|
|
|
return generateFuturesOverview();
|
|
|
|
@ -216,7 +222,7 @@ export const fetchMarketOverview = async () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
// 直接使用测试数据源
|
|
|
|
// 直接使用测试数据源
|
|
|
|
console.log('使用测试数据源');
|
|
|
|
logger.log('使用测试数据源');
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 300));
|
|
|
|
return generateFuturesOverview();
|
|
|
|
return generateFuturesOverview();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -224,7 +230,7 @@ export const fetchMarketOverview = async () => {
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('获取市场概览失败:', error);
|
|
|
|
logger.error('获取市场概览失败:', error);
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取市场概览失败,请检查数据源配置');
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取市场概览失败,请检查数据源配置');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -243,26 +249,31 @@ export const fetchMarketDetail = async (symbol: string) => {
|
|
|
|
|
|
|
|
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
console.log('尝试使用 service_implementation API 获取品种详情...');
|
|
|
|
logger.log('尝试使用 service_implementation API 获取品种详情...');
|
|
|
|
|
|
|
|
|
|
|
|
// 构建合约符号(使用大写代码,因为 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)}05`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取合约详情
|
|
|
|
// 获取合约详情
|
|
|
|
console.log(`获取合约${contractSymbol}详情...`);
|
|
|
|
logger.log(`获取合约${contractSymbol}详情...`);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === contractSymbol);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === contractSymbol);
|
|
|
|
|
|
|
|
|
|
|
|
if (!contract) {
|
|
|
|
if (!contract) {
|
|
|
|
console.warn(`合约${contractSymbol}不存在,尝试使用其他数据源`);
|
|
|
|
logger.warn(`合约${contractSymbol}不存在,尝试使用其他数据源`);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 更新未来合约的中文名称
|
|
|
|
|
|
|
|
future.name = `${contract.product_name || future.name} - ${future.code}`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取分析数据
|
|
|
|
// 获取分析数据
|
|
|
|
console.log(`分析合约${contractSymbol}...`);
|
|
|
|
logger.log(`分析合约${contractSymbol}...`);
|
|
|
|
|
|
|
|
logger.log(`before analyzeMarket: symbol=${contractSymbol},time=${new Date().toISOString()}`);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(contractSymbol);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(contractSymbol);
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
|
|
|
|
logger.log(`after analyzeMarket: symbol=${contractSymbol},time=${new Date().toISOString()}`);
|
|
|
|
|
|
|
|
|
|
|
|
// 获取交易建议
|
|
|
|
// 获取交易建议
|
|
|
|
console.log(`获取合约${contractSymbol}交易建议...`);
|
|
|
|
logger.log(`获取合约${contractSymbol}交易建议...`);
|
|
|
|
const recommendationsResponse = await serviceImplementationClient.getRecommendations(contractSymbol);
|
|
|
|
const recommendationsResponse = await serviceImplementationClient.getRecommendations(contractSymbol);
|
|
|
|
const recommendation = recommendationsResponse.data[0];
|
|
|
|
const recommendation = recommendationsResponse.data[0];
|
|
|
|
|
|
|
|
|
|
|
|
@ -322,13 +333,13 @@ export const fetchMarketDetail = async (symbol: string) => {
|
|
|
|
aiAnalysis: `趋势:${analysis.trend || '中性'} | 概率:${analysis.probability ? Math.round(analysis.probability * 100) : 50}% | 方向:${analysis.direction || '观望'}`
|
|
|
|
aiAnalysis: `趋势:${analysis.trend || '中性'} | 概率:${analysis.probability ? Math.round(analysis.probability * 100) : 50}% | 方向:${analysis.direction || '观望'}`
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('使用 service_implementation API 获取品种详情成功');
|
|
|
|
logger.log('使用 service_implementation API 获取品种详情成功');
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.warn('service_implementation API 未返回数据,尝试使用其他数据源');
|
|
|
|
logger.warn('service_implementation API 未返回数据,尝试使用其他数据源');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('service_implementation API 获取失败:', error);
|
|
|
|
logger.error('service_implementation API 获取失败:', error);
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -408,10 +419,10 @@ export const fetchMarketDetail = async (symbol: string) => {
|
|
|
|
aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近`
|
|
|
|
aiAnalysis: `MACD:金叉向上 | RSI:${Math.floor(Math.random() * 80) + 10}(中性) | 布林带:中轨附近`
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('TQSDK数据源获取失败:', error);
|
|
|
|
logger.error('TQSDK数据源获取失败:', error);
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
console.log('切换到测试数据源');
|
|
|
|
logger.log('切换到测试数据源');
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
return generateFutureData(symbol, future.name);
|
|
|
|
return generateFutureData(symbol, future.name);
|
|
|
|
@ -422,7 +433,7 @@ export const fetchMarketDetail = async (symbol: string) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
// 直接使用测试数据源
|
|
|
|
// 直接使用测试数据源
|
|
|
|
console.log('使用测试数据源');
|
|
|
|
logger.log('使用测试数据源');
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
return generateFutureData(symbol, future.name);
|
|
|
|
return generateFutureData(symbol, future.name);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -430,7 +441,7 @@ export const fetchMarketDetail = async (symbol: string) => {
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取品种${symbol}详情失败:`, error);
|
|
|
|
logger.error(`获取品种${symbol}详情失败:`, error);
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取品种详情失败,请检查数据源配置');
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取品种详情失败,请检查数据源配置');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -447,7 +458,7 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
|
|
|
|
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
console.log('尝试使用 service_implementation API 获取K线数据...');
|
|
|
|
logger.log('尝试使用 service_implementation API 获取K线数据...');
|
|
|
|
|
|
|
|
|
|
|
|
// 构建合约符号(使用大写代码,因为 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)}05`;
|
|
|
|
@ -481,7 +492,7 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取K线数据
|
|
|
|
// 获取K线数据
|
|
|
|
console.log(`获取合约${contractSymbol}K线数据,周期: ${duration}...`);
|
|
|
|
logger.log(`获取合约${contractSymbol}K线数据,周期: ${duration}...`);
|
|
|
|
const klineResponse = await serviceImplementationClient.getKlineData(contractSymbol, duration, 30);
|
|
|
|
const klineResponse = await serviceImplementationClient.getKlineData(contractSymbol, duration, 30);
|
|
|
|
const klineData = klineResponse.data;
|
|
|
|
const klineData = klineResponse.data;
|
|
|
|
|
|
|
|
|
|
|
|
@ -496,13 +507,13 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
volume: item.volume
|
|
|
|
volume: item.volume
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
console.log('使用 service_implementation API 获取K线数据成功');
|
|
|
|
logger.log('使用 service_implementation API 获取K线数据成功');
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.warn('service_implementation API 未返回K线数据,尝试使用其他数据源');
|
|
|
|
logger.warn('service_implementation API 未返回K线数据,尝试使用其他数据源');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('service_implementation API 获取K线数据失败:', error);
|
|
|
|
logger.error('service_implementation API 获取K线数据失败:', error);
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -536,10 +547,10 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
volume: item.volume
|
|
|
|
volume: item.volume
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('TQSDK数据源获取失败:', error);
|
|
|
|
logger.error('TQSDK数据源获取失败:', error);
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
console.log('切换到测试数据源');
|
|
|
|
logger.log('切换到测试数据源');
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
return generateKlineData(30);
|
|
|
|
return generateKlineData(30);
|
|
|
|
@ -550,7 +561,7 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
// 直接使用测试数据源
|
|
|
|
// 直接使用测试数据源
|
|
|
|
console.log('使用测试数据源');
|
|
|
|
logger.log('使用测试数据源');
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
return generateKlineData(30);
|
|
|
|
return generateKlineData(30);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@ -558,7 +569,7 @@ export const fetchKlineData = async (symbol: string, period: string) => {
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取合约${symbol}K线数据失败:`, error);
|
|
|
|
logger.error(`获取合约${symbol}K线数据失败:`, error);
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取K线数据失败,请检查数据源配置');
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取K线数据失败,请检查数据源配置');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -569,10 +580,10 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
// 首先尝试使用 service_implementation API
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
console.log('尝试使用 service_implementation API 获取市场热点...');
|
|
|
|
logger.log('尝试使用 service_implementation API 获取市场热点...');
|
|
|
|
|
|
|
|
|
|
|
|
// 先获取合约列表
|
|
|
|
// 先获取合约列表
|
|
|
|
console.log('获取合约列表...');
|
|
|
|
logger.log('获取合约列表...');
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts();
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts();
|
|
|
|
const allContracts = contractsResponse.data;
|
|
|
|
const allContracts = contractsResponse.data;
|
|
|
|
|
|
|
|
|
|
|
|
@ -592,7 +603,7 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为数组
|
|
|
|
// 转换为数组
|
|
|
|
const contractList = Array.from(uniqueContracts.values());
|
|
|
|
const contractList = Array.from(uniqueContracts.values());
|
|
|
|
console.log(`获取到 ${contractList.length} 个独特品种`);
|
|
|
|
logger.log(`获取到 ${contractList.length} 个独特品种`);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用获取到的合约列表
|
|
|
|
// 使用获取到的合约列表
|
|
|
|
const hotspots = [];
|
|
|
|
const hotspots = [];
|
|
|
|
@ -602,17 +613,20 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`;
|
|
|
|
const symbol = `${future.code}${new Date().getFullYear().toString().slice(-2)}05`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取合约详情
|
|
|
|
// 获取合约详情
|
|
|
|
console.log(`获取合约${symbol}详情...`);
|
|
|
|
logger.log(`获取合约${symbol}详情...`);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contractsResponse = await serviceImplementationClient.getContracts(future.exchange, future.code);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === symbol);
|
|
|
|
const contract = contractsResponse.data.find((c: any) => c.symbol === symbol);
|
|
|
|
|
|
|
|
|
|
|
|
if (!contract) {
|
|
|
|
if (!contract) {
|
|
|
|
console.warn(`合约${symbol}不存在,跳过`);
|
|
|
|
logger.warn(`合约${symbol}不存在,跳过`);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新未来合约的中文名称
|
|
|
|
|
|
|
|
future.name = `${contract.product_name || future.name} - ${future.code}`;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取分析数据
|
|
|
|
// 获取分析数据
|
|
|
|
console.log(`分析合约${symbol}...`);
|
|
|
|
logger.log(`分析合约${symbol}...`);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(symbol);
|
|
|
|
const analysisResponse = await serviceImplementationClient.analyzeMarket(symbol);
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
const analysis = analysisResponse.data;
|
|
|
|
|
|
|
|
|
|
|
|
@ -623,7 +637,7 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
volume: analysis.volume || Math.floor(Math.random() * 1000000) + 100000
|
|
|
|
volume: analysis.volume || Math.floor(Math.random() * 1000000) + 100000
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
logger.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -635,13 +649,13 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
.sort((a, b) => Math.abs(b.change) - Math.abs(a.change))
|
|
|
|
.sort((a, b) => Math.abs(b.change) - Math.abs(a.change))
|
|
|
|
.slice(0, 10);
|
|
|
|
.slice(0, 10);
|
|
|
|
|
|
|
|
|
|
|
|
console.log('使用 service_implementation API 获取市场热点成功');
|
|
|
|
logger.log('使用 service_implementation API 获取市场热点成功');
|
|
|
|
return sortedHotspots;
|
|
|
|
return sortedHotspots;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.warn('service_implementation API 未返回市场热点数据,尝试使用其他数据源');
|
|
|
|
logger.warn('service_implementation API 未返回市场热点数据,尝试使用其他数据源');
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('service_implementation API 获取市场热点失败:', error);
|
|
|
|
logger.error('service_implementation API 获取市场热点失败:', error);
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
// service_implementation API 失败,尝试使用其他数据源
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -675,7 +689,7 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
volume: tick.volume
|
|
|
|
volume: tick.volume
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
logger.error(`获取合约${future.code}行情失败:`, error);
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
// 跳过获取失败的合约
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -686,10 +700,10 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
.sort((a, b) => Math.abs(b.change) - Math.abs(a.change))
|
|
|
|
.sort((a, b) => Math.abs(b.change) - Math.abs(a.change))
|
|
|
|
.slice(0, 10);
|
|
|
|
.slice(0, 10);
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('TQSDK数据源获取失败:', error);
|
|
|
|
logger.error('TQSDK数据源获取失败:', error);
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
// TQSDK数据源失败,尝试使用测试数据源
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
if (dataSourceConfig.test?.enabled) {
|
|
|
|
console.log('切换到测试数据源');
|
|
|
|
logger.log('切换到测试数据源');
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
// 启用了测试数据源,使用测试数据
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
const overview = generateFuturesOverview();
|
|
|
|
const overview = generateFuturesOverview();
|
|
|
|
@ -710,7 +724,7 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
} else if (dataSourceConfig.test?.enabled) {
|
|
|
|
// 直接使用测试数据源
|
|
|
|
// 直接使用测试数据源
|
|
|
|
console.log('使用测试数据源');
|
|
|
|
logger.log('使用测试数据源');
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
|
|
const overview = generateFuturesOverview();
|
|
|
|
const overview = generateFuturesOverview();
|
|
|
|
// 按涨跌幅排序,返回前10个
|
|
|
|
// 按涨跌幅排序,返回前10个
|
|
|
|
@ -728,7 +742,7 @@ export const fetchMarketHotspots = async () => {
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
throw new Error('无可用数据源,请在管理配置中启用至少一个数据源');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
} catch (error) {
|
|
|
|
console.error('获取市场热点失败:', error);
|
|
|
|
logger.error('获取市场热点失败:', error);
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
// 直接返回友好的错误提示
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取市场热点失败,请检查数据源配置');
|
|
|
|
throw new Error(error instanceof Error ? error.message : '获取市场热点失败,请检查数据源配置');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|