From 51a3ea5e2feee6031ffea5f29fccf87ee01d45ea Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 29 Apr 2025 11:45:24 +0800 Subject: [PATCH] update --- cryptoai/__pycache__/main.cpython-313.pyc | Bin 1444 -> 1457 bytes .../__pycache__/crypto_agent.cpython-313.pyc | Bin 19010 -> 19639 bytes cryptoai/agents/crypto_agent.py | 170 ++++++++++-------- cryptoai/agents/gold_agent.py | 33 +++- cryptoai/config/config.yaml | 12 +- cryptoai/main.py | 7 +- requirements.txt | 2 +- 7 files changed, 136 insertions(+), 88 deletions(-) diff --git a/cryptoai/__pycache__/main.cpython-313.pyc b/cryptoai/__pycache__/main.cpython-313.pyc index f39fe6e47b3432f9ae0c02440bcb5822dd1b187e..a53f14530cf69e10ae700317f0cb58f5af621727 100644 GIT binary patch delta 211 zcmZ3&y^)*mGcPX}0}!Nm31ld_5DziFj yOlDzus|GUY7Ds%1USe))eEdp=&pe-=>z b0iYSTIBatBQ%ZAE?TXYUtFU&mr~(B6YM(2H diff --git a/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc b/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc index 1a88d39a3306a3fe207aeb7deca03eaffe1c0691..91ce613ead2879d09698a94238dafce660d1f355 100644 GIT binary patch delta 3363 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%0DRj$FYAr<%eloaCrvX z8bw6P>l# zSt~l*v9o>ktT6tZFcTA;?Sk|4rNX%K371jq9KH2&$~h4)e8>W0QM#ceF^Y|~q|}b; zb%+0Y>071OxSdf`j+QM(=F-O%mkKlL0v)6_O6_lsy*?%`ly>6M&NSyu+dOG+h3IX< z-llYUVl$qnb57oe0wr(v;m=j8&{II|c-m?yE=Ja8K8@Xp4-BtpfdC9z_ zOsEBOP}Ej!YE4V*(%GdM!P_O6yG3o!);J9;uFNwu&{`HXpKlie>xkn4ph!OJ#-gP@ zX{`$tBe$k*L7{kDG={M;{6$74@&B6R$dB@e=9ZxV{l|I@!P|lSVJ&mJUN@{_?x+|d zPg5unGSYvc(XT?&XiHv3$0!snEJu+xqY3WrHZgiqO=3xnoGm64V~l87X+dAqXzOIV z6bKu4eDH~KUidb6mn!1{`mzH(7^70DiiWoX=2jN1F0=#AbfAGN0pvIzBL86df`3^6g9oFCOp zDe2==QC-vt1~M`7MzejtXMZcDa1*ul*O+8G(+VZap9sv6Qvje>`>UESO0)W1qMZlZ z8jzy*%(DWk#C=XHD-AM?Ra+4N1Bw!JpB&!%g%iK*_@w$t@Kf z9kiA}im_x)(GJFvIJ9h7o?f Dict[str, Any]: + """ + 分析单个交易对 + """ + results = {} + + print(f"\n开始分析{symbol}...") + + # 获取并处理数据 + raw_data = self.fetch_historical_data(symbol, days=self.crypto_config['historical_days']) + + if not raw_data.empty: + processed_data = self.process_data(symbol, raw_data) + + # 准备市场数据 + market_data = { + "symbol": symbol, + "current_price": float(processed_data['close'].iloc[-1]), + # "price_change_24h": float(processed_data['close'].iloc[-1] - processed_data['close'].iloc[-24]), + # "price_change_percentage_24h": float((processed_data['close'].iloc[-1] - processed_data['close'].iloc[-24]) / processed_data['close'].iloc[-24] * 100), + "historical_prices": processed_data['close'].tail(100).tolist(), + "volumes": processed_data['volume'].tail(100).tolist(), + "technical_indicators": { + "rsi": float(processed_data['RSI'].iloc[-1]), + "macd": float(processed_data['MACD'].iloc[-1]), + "macd_signal": float(processed_data['MACD_Signal'].iloc[-1]), + "bollinger_upper": float(processed_data['Bollinger_Upper'].iloc[-1]), + "bollinger_lower": float(processed_data['Bollinger_Lower'].iloc[-1]), + "ma5": float(processed_data['MA5'].iloc[-1]), + "ma10": float(processed_data['MA10'].iloc[-1]), + "ma20": float(processed_data['MA20'].iloc[-1]), + "ma50": float(processed_data['MA50'].iloc[-1]), + "atr": float(processed_data['ATR'].iloc[-1]) + }, + "klines": processed_data[['open', 'high', 'low', 'close', 'volume']].tail(100).to_dict('records') + } + + # 将市场数据格式化为适合大模型的格式 + formatted_data = self._format_market_data(market_data) + + # 构建提示词 + prompt = self._build_market_analysis_prompt(formatted_data) + + # 调用API获取分析和交易建议 + response, usage = self.deepseek_api.call_model(prompt, task_type="交易分析", symbol=symbol) + + # 解析响应 + analysis_result = self.deepseek_api.extract_json_from_response(response) + + # 添加token使用信息 + if usage: + analysis_result["_token_usage"] = usage + + # 整合结果 + results[symbol] = { + "analysis": analysis_result, + "timestamp": datetime.now().isoformat() + } + + # 保存分析结果到数据库 + try: + # 保存到数据库 + saved = self.db_manager.save_analysis_result( + agent='crypto', + symbol=symbol, + time_interval=self.time_interval, + analysis_result=analysis_result + ) + if saved: + print(f"{symbol}分析结果已保存到数据库") + else: + print(f"{symbol}分析结果保存到数据库失败") + except Exception as e: + print(f"保存{symbol}分析结果到数据库时出错: {e}") + + print(f"{symbol}分析完成") + else: + print(f"跳过{symbol}分析,无法获取数据") + + return results + def analyze_all_symbols(self) -> Dict[str, Dict[str, Any]]: """ 分析所有支持的交易对 @@ -229,81 +310,13 @@ class CryptoAgent: for symbol in self.symbols: print(f"\n开始分析{symbol}...") - # 获取并处理数据 - raw_data = self.fetch_historical_data(symbol, days=self.crypto_config['historical_days']) - - if not raw_data.empty: - processed_data = self.process_data(symbol, raw_data) - - # 准备市场数据 - market_data = { - "symbol": symbol, - "current_price": float(processed_data['close'].iloc[-1]), - # "price_change_24h": float(processed_data['close'].iloc[-1] - processed_data['close'].iloc[-24]), - # "price_change_percentage_24h": float((processed_data['close'].iloc[-1] - processed_data['close'].iloc[-24]) / processed_data['close'].iloc[-24] * 100), - "historical_prices": processed_data['close'].tail(100).tolist(), - "volumes": processed_data['volume'].tail(100).tolist(), - "technical_indicators": { - "rsi": float(processed_data['RSI'].iloc[-1]), - "macd": float(processed_data['MACD'].iloc[-1]), - "macd_signal": float(processed_data['MACD_Signal'].iloc[-1]), - "bollinger_upper": float(processed_data['Bollinger_Upper'].iloc[-1]), - "bollinger_lower": float(processed_data['Bollinger_Lower'].iloc[-1]), - "ma5": float(processed_data['MA5'].iloc[-1]), - "ma10": float(processed_data['MA10'].iloc[-1]), - "ma20": float(processed_data['MA20'].iloc[-1]), - "ma50": float(processed_data['MA50'].iloc[-1]), - "atr": float(processed_data['ATR'].iloc[-1]) - }, - "klines": processed_data[['open', 'high', 'low', 'close', 'volume']].tail(100).to_dict('records') - } - - # 将市场数据格式化为适合大模型的格式 - formatted_data = self._format_market_data(market_data) - - # 构建提示词 - prompt = self._build_market_analysis_prompt(formatted_data) - - # 调用API获取分析和交易建议 - response, usage = self.deepseek_api.call_model(prompt, task_type="交易分析", symbol=symbol) - - # 解析响应 - analysis_result = self.deepseek_api.extract_json_from_response(response) - - # 添加token使用信息 - if usage: - analysis_result["_token_usage"] = usage - - # 整合结果 - results[symbol] = { - "analysis": analysis_result, - "timestamp": datetime.now().isoformat() - } - - # 保存分析结果到数据库 - try: - # 保存到数据库 - saved = self.db_manager.save_analysis_result( - agent='crypto', - symbol=symbol, - time_interval=self.time_interval, - analysis_result=analysis_result - ) - if saved: - print(f"{symbol}分析结果已保存到数据库") - else: - print(f"{symbol}分析结果保存到数据库失败") - except Exception as e: - print(f"保存{symbol}分析结果到数据库时出错: {e}") - - print(f"{symbol}分析完成") - else: - print(f"跳过{symbol}分析,无法获取数据") + single_result = self.analyze_symbol(symbol) + results[symbol] = single_result[symbol] return results - def run_analysis_cycle(self) -> Dict[str, Any]: + def run_analysis_cycle(self, symbol: Optional[str] = None) -> Dict[str, Any]: """ 运行一个完整的分析周期 @@ -312,7 +325,10 @@ class CryptoAgent: """ print(f"开始新的分析周期,时间:{datetime.now().isoformat()}") - results = self.analyze_all_symbols() + if symbol: + results = self.analyze_symbol(symbol) + else: + results = self.analyze_all_symbols() # 保存分析结果 timestamp = datetime.now().strftime("%Y%m%d%H%M%S") @@ -343,7 +359,7 @@ class CryptoAgent: 把分析的JSON结果调用大模型转化成交易建议 """ prompt = f""" - 请对以下加密货币市场分析的JSON结果进行深入分析, 转化成包含:分析时间,技术分析,支撑位,压力位, 建议买点,卖点,止损位,止盈位,仓位建议, 增加适当的emoji便于阅读, 简单明了。 + 请对以下加密货币市场分析的JSON结果进行深入分析, 转化成包含:分析时间,分析时间级别,技术分析,支撑位,压力位, 建议买点,卖点,止损位,止盈位,仓位建议, 增加适当的emoji便于阅读, 简单明了。 分析 JSON 结果: {results} @@ -392,7 +408,7 @@ class CryptoAgent: except Exception as e: print(f"导出 token 使用情况时出错: {e}") - def start_agent(self) -> None: + def start_agent(self, symbol: Optional[str] = None) -> None: """ 启动智能体 @@ -402,11 +418,13 @@ class CryptoAgent: print("启动加密货币分析智能体...") try: - self.run_analysis_cycle() + if symbol: + self.run_analysis_cycle(symbol) + else: + self.run_analysis_cycle() # 导出最终的token使用情况 self._export_token_usage() - except KeyboardInterrupt: print("\n智能体已停止") # 导出最终的token使用情况 diff --git a/cryptoai/agents/gold_agent.py b/cryptoai/agents/gold_agent.py index 59029dd..2dc8fac 100644 --- a/cryptoai/agents/gold_agent.py +++ b/cryptoai/agents/gold_agent.py @@ -276,7 +276,7 @@ class GoldAgent: "seasonal_factor": float(processed_data['seasonal_factor'].iloc[-1]), "gold_bull_signal": float(processed_data['gold_bull_signal'].iloc[-1]) }, - "klines": processed_data[['open', 'high', 'low', 'close', 'volume']].tail(30).to_dict('records') + "klines": processed_data[['open', 'high', 'low', 'close', 'volume']].tail(100).to_dict('records') } # 将市场数据格式化为适合大模型的格式 @@ -331,8 +331,35 @@ class GoldAgent: # 导出 DeepSeek API token 使用情况 self._export_token_usage() - - return results + + # 把分析的JSON结果调用大模型转化成交易建议 + trading_suggestions = self.convert_analysis_to_trading_suggestions(results) + print(f"交易建议:{trading_suggestions}") + + if self.dingtalk_bot: + self.dingtalk_bot.send_markdown(title="黄金交易建议", text=trading_suggestions) + + return results, trading_suggestions + + def convert_analysis_to_trading_suggestions(self, results: Dict[str, Any]) -> str: + """ + 把分析的JSON结果调用大模型转化成交易建议 + """ + prompt = f""" + 请对以下黄金市场分析的JSON结果进行深入分析, 转化成包含:分析时间,技术分析,支撑位,压力位, 建议买点,卖点,止损位,止盈位,仓位建议, 增加适当的emoji便于阅读, 简单明了。 + + 分析 JSON 结果: + {results} + """ + + system_prompt = """ + 你是一个专业的黄金分析助手,你擅长分析市场趋势、预测价格走向和提供交易建议,请始终使用中文回复,并确保输出格式规范的Markdown。 + """ + response, usage = self.deepseek_api.call_model(prompt, system_prompt=system_prompt, task_type="交易建议") + + message = self.deepseek_api.extract_text_from_response(response) + + return message def _export_token_usage(self) -> None: """ diff --git a/cryptoai/config/config.yaml b/cryptoai/config/config.yaml index a96c0da..abd1052 100644 --- a/cryptoai/config/config.yaml +++ b/cryptoai/config/config.yaml @@ -25,13 +25,13 @@ alltick: # 加密货币设置 crypto: base_currencies: - - "BTC" - - "ETH" + # - "BTC" + # - "ETH" # - "SOL" # - "SUI" - # - "XRP" + - "CETUS" quote_currency: "USDT" - time_interval: "1h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d + time_interval: "4h" # 可选: 1m, 5m, 15m, 30m, 1h, 4h, 1d historical_days: 30 # 黄金市场分析配置 @@ -39,9 +39,9 @@ gold: # 黄金交易对 symbols: ["GOLD"] # 历史数据天数 - historical_days: 180 + historical_days: 30 # 时间间隔 - time_interval: "1d" + time_interval: "4h" # 数据设置 diff --git a/cryptoai/main.py b/cryptoai/main.py index ce50da3..76c5685 100644 --- a/cryptoai/main.py +++ b/cryptoai/main.py @@ -18,7 +18,7 @@ from cryptoai.utils.config_loader import ConfigLoader def main(): try: - print("程序启动") + print("定时程序启动") # 设置每个4小时运行一次 schedule.every(4).hours.do(CryptoAgent().start_agent) @@ -26,7 +26,10 @@ def main(): while True: schedule.run_pending() time.sleep(1) - # CryptoAgent().start_agent() + + + # GoldAgent().start_agent() + # CryptoAgent().start_agent('BTCUSDT') except KeyboardInterrupt: print("\n程序已退出") diff --git a/requirements.txt b/requirements.txt index 475b634..ccbe800 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ numpy==1.24.3 sqlalchemy==2.0.19 pymysql==1.1.0 requests==2.31.0 -schedule==1.2.0 \ No newline at end of file +schedule==1.2.0