# Service main application from flask import Flask, request, jsonify import sys import os import pandas as pd # 添加项目根目录到 Python 路径 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from qihuo_analyzer.data.data_fetcher import DataFetcher from qihuo_analyzer.data.data_storage import DataStorage from qihuo_analyzer.modules.deepseek_agent import DeepseekAgent from qihuo_analyzer.utils.config_manager import config_manager app = Flask(__name__) # 初始化组件 data_fetcher = DataFetcher() data_storage = DataStorage() deepseek_agent = DeepseekAgent() # 连接 API print("正在连接 API...") connect_success = data_fetcher.connect() if connect_success: print("API 连接成功,可以获取真实数据") else: print("API 连接失败,将使用模拟数据") # 健康检查接口 @app.route('/health', methods=['GET']) def health_check(): return jsonify({'status': 'ok', 'message': 'Service is running'}) # 合约数据获取接口 @app.route('/api/contracts', methods=['GET']) def get_contracts(): try: exchange = request.args.get('exchange', '') symbol = request.args.get('symbol', '') contracts = data_fetcher.get_contracts(exchange=exchange, symbol=symbol) return jsonify({'status': 'success', 'data': contracts}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # K线数据获取接口 @app.route('/api/kline', methods=['GET']) def get_kline(): try: symbol = request.args.get('symbol', '') duration = request.args.get('duration', '1m') limit = int(request.args.get('limit', 100)) if not symbol: return jsonify({'status': 'error', 'message': 'Symbol is required'}), 400 # 尝试从数据库获取,如果没有则从数据源获取 df = data_storage.get_kline_data(symbol, duration, limit) if df.empty: # 从数据源获取 df = data_fetcher.get_kline_data(symbol, duration, limit) # 保存到数据库 data_storage.save_kline_data(symbol, duration, df) # 转换为字典格式 kline_data = [] for idx, row in df.iterrows(): kline_data.append({ 'datetime': idx.isoformat(), 'open': float(row['open']), 'high': float(row['high']), 'low': float(row['low']), 'close': float(row['close']), 'volume': int(row['volume']), 'open_interest': int(row['open_interest']) }) return jsonify({'status': 'success', 'data': kline_data}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # DeepSeek 分析接口 @app.route('/api/analyze', methods=['POST']) def analyze(): try: data = request.get_json() symbol = data.get('symbol', '') duration = data.get('duration', '1m') analysis_type = data.get('analysis_type', 'technical') if not symbol: return jsonify({'status': 'error', 'message': 'Symbol is required'}), 400 # 获取K线数据 df = data_fetcher.get_kline_data(symbol, duration, 1000) # 保存到数据库 data_storage.save_kline_data(symbol, duration, df) # 执行分析 analysis_result = deepseek_agent.analyze_market(symbol, df) # 保存分析结果 data_storage.save_analysis_result(analysis_result) return jsonify({'status': 'success', 'data': analysis_result}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # 交易建议接口 @app.route('/api/recommendations', methods=['GET']) def get_recommendations(): try: symbol = request.args.get('symbol', '') status = request.args.get('status', '') if not symbol: return jsonify({'status': 'error', 'message': 'Symbol is required'}), 400 df = data_storage.get_trade_recommendations(symbol, status) # 转换为字典格式 recommendations = [] for _, row in df.iterrows(): recommendations.append({ 'id': int(row['id']), 'symbol': row['symbol'], 'timestamp': row['timestamp'], 'direction': row['direction'], 'entry_price': float(row['entry_price']) if not pd.isna(row['entry_price']) else None, 'stop_loss': float(row['stop_loss']) if not pd.isna(row['stop_loss']) else None, 'target_price': float(row['target_price']) if not pd.isna(row['target_price']) else None, 'position_size': float(row['position_size']) if not pd.isna(row['position_size']) else None, 'execution_plan': row['execution_plan'], 'risk_tips': row['risk_tips'], 'status': row['status'], 'created_at': row['created_at'] }) return jsonify({'status': 'success', 'data': recommendations}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # 风险监控接口 @app.route('/api/risk', methods=['POST']) def monitor_risk(): try: data = request.get_json() symbol = data.get('symbol', '') current_price = data.get('current_price', 0) entry_price = data.get('entry_price', 0) stop_loss = data.get('stop_loss', 0) target_price = data.get('target_price', 0) if not symbol: return jsonify({'status': 'error', 'message': 'Symbol is required'}), 400 # 计算当前利润 current_profit = current_price - entry_price # 评估风险状态 risk_status = 'normal' if abs(current_profit) > (entry_price * 0.05): risk_status = 'high' # 保存风险监控数据 risk_data = { 'symbol': symbol, 'current_price': current_price, 'entry_price': entry_price, 'stop_loss': stop_loss, 'target_price': target_price, 'current_profit': current_profit, 'risk_status': risk_status } data_storage.save_risk_monitoring(risk_data) return jsonify({'status': 'success', 'data': risk_data}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 # 分析历史接口 @app.route('/api/analysis/history', methods=['GET']) def get_analysis_history(): try: symbol = request.args.get('symbol', '') limit = int(request.args.get('limit', 100)) if not symbol: return jsonify({'status': 'error', 'message': 'Symbol is required'}), 400 df = data_storage.get_analysis_results(symbol, limit) # 转换为字典格式 history = [] for _, row in df.iterrows(): history.append({ 'id': int(row['id']), 'symbol': row['symbol'], 'timestamp': row['timestamp'], 'trend': row['trend'], 'probability': float(row['probability']) if not pd.isna(row['probability']) else None, 'direction': row['direction'], 'cycle': row['cycle'], 'atr': float(row['atr']) if not pd.isna(row['atr']) else None, 'adx': float(row['adx']) if not pd.isna(row['adx']) else None, 'support': float(row['support']) if not pd.isna(row['support']) else None, 'resistance': float(row['resistance']) if not pd.isna(row['resistance']) else None, 'stop_loss': float(row['stop_loss']) if not pd.isna(row['stop_loss']) else None, 'target_price': float(row['target_price']) if not pd.isna(row['target_price']) else None, 'position_size': float(row['position_size']) if not pd.isna(row['position_size']) else None, 'risk_ratio': float(row['risk_ratio']) if not pd.isna(row['risk_ratio']) else None, 'fund_flow': row['fund_flow'], 'signals': row['signals'], 'created_at': row['created_at'] }) return jsonify({'status': 'success', 'data': history}) except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)