diff --git a/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc b/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc index 8080a57..1eb923d 100644 Binary files a/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc and b/cryptoai/agents/__pycache__/crypto_agent.cpython-313.pyc differ diff --git a/cryptoai/agents/crypto_agent.py b/cryptoai/agents/crypto_agent.py index d963e23..e5f8476 100644 --- a/cryptoai/agents/crypto_agent.py +++ b/cryptoai/agents/crypto_agent.py @@ -18,7 +18,7 @@ from models.data_processor import DataProcessor from utils.config_loader import ConfigLoader from utils.dingtalk_bot import DingTalkBot from utils.discord_bot import DiscordBot -from models.analysis_result import AnalysisResultManager +from cryptoai.models.analysis_result import AnalysisResultManager from utils.db_manager import SessionLocal class CryptoAgent: diff --git a/cryptoai/tasks/token_selector.py b/cryptoai/tasks/token_selector.py new file mode 100644 index 0000000..344c6b0 --- /dev/null +++ b/cryptoai/tasks/token_selector.py @@ -0,0 +1,172 @@ +from binance.client import Client +import pandas as pd +import numpy as np +from datetime import datetime +import requests +from rich.console import Console +from rich.table import Table +from rich.panel import Panel +from rich.text import Text +from rich import box + + +# 初始化 Binance API +api_key = 'HCpeel8g6fsTK2630b7BvGBcS09Z3qfXkLVcAY2JkpaiMm1J6DWRvoQZBQlElDJg' +api_secret = 'TySs6onlHOTrGzV8fMdDxLKTWWYnQ4rCHVAmjrcHby17acKflmo7xVTWVsbqtxe7' +client = Client(api_key, api_secret) + +# 获取 24h 涨幅和成交量 +url = "https://api.binance.com/api/v3/ticker/24hr" +response = requests.get(url) +tickers = response.json() + +df = pd.DataFrame(tickers) +df = df[df['symbol'].str.endswith('USDT') & (~df['symbol'].str.contains('UP|DOWN|BULL|BEAR'))] +df['priceChangePercent'] = pd.to_numeric(df['priceChangePercent'], errors='coerce') +df['quoteVolume'] = pd.to_numeric(df['quoteVolume'], errors='coerce') + +# 初筛条件,成交量大于3000万,24h涨幅小于20% +filtered = df[(df['quoteVolume'] > 3e7) & (df['priceChangePercent'] < 20)] + +top_symbols = filtered.sort_values(by='priceChangePercent', ascending=False).head(50)['symbol'].tolist() + +# 技术指标分析函数 +def analyze_symbol(symbol, interval='1h', limit=1000): + try: + klines = client.get_klines(symbol=symbol, interval=interval, limit=limit) + df = pd.DataFrame(klines, columns=['time', 'open', 'high', 'low', 'close', 'volume', + 'close_time', 'quote_volume', 'trades', + 'taker_buy_base', 'taker_buy_quote', 'ignore']) + df['close'] = pd.to_numeric(df['close']) + df['volume'] = pd.to_numeric(df['volume']) + + # 计算指标 + df['ema20'] = df['close'].ewm(span=20).mean() + df['ema50'] = df['close'].ewm(span=50).mean() + df['ema200'] = df['close'].ewm(span=200).mean() + df['vol_ma20'] = df['volume'].rolling(20).mean() + + # 当前状态 + latest = df.iloc[-1] + + # 成交量突增 + vol_spike = latest['volume'] > 1.5 * latest['vol_ma20'] + + # 上涨趋势 + bull_trend = latest['ema20'] > latest['ema50'] > latest['ema200'] + + # 价格突破 + price_break = latest['close'] > df['close'].rolling(20).max().shift(1).iloc[-1] + + # 是否是箱体运动 + # 计算200根K线内的最高价和最低价 + high_200 = df['high'].rolling(200).max().iloc[-1] + low_200 = df['low'].rolling(200).min().iloc[-1] + # 计算当前价格与200根K线最高价和最低价的距离 + price_distance_high = (latest['close'] - high_200) / high_200 + price_distance_low = (latest['close'] - low_200) / low_200 + + # 是否是箱体运动 + box_movement = price_distance_high < 0.05 and price_distance_low < 0.05 + + score = int(vol_spike) + int(bull_trend) + int(price_break) + int(box_movement) + + return { + '币种': symbol, + '上涨趋势': '是' if bull_trend else '否', + '价格突破': '是' if price_break else '否', + '箱体运动': '是' if box_movement else '否', + '得分': score + } + + except Exception as e: + return { + '币种': symbol, + '上涨趋势': '错误', + '价格突破': '错误', + '箱体运动': '错误', + '得分': 0 + } + +if __name__ == "__main__": + # 执行分析 + results = [analyze_symbol(sym) for sym in top_symbols] + df_result = pd.DataFrame(results) + + # 只取上涨趋势为是 + df_result = df_result[df_result['上涨趋势'] == '是'] + + # 按照得分排序 + df_result = df_result.sort_values(by='得分', ascending=False) + + # 取前10个 + df_final = df_result.head(10) + + # 创建 Rich 控制台 + console = Console() + + # 创建标题面板 + title_panel = Panel( + Text("🔥 今日潜在强势币种分析 🔥", style="bold red", justify="center"), + style="bright_blue", + box=box.DOUBLE + ) + + # 创建时间信息 + time_text = Text(f"📅 分析时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", style="dim") + + # 创建漂亮的表格 + table = Table( + title="💰 币种分析结果", + show_header=True, + header_style="bold magenta", + box=box.ROUNDED, + title_style="bold cyan" + ) + + # 添加列 + table.add_column("币种", style="bold yellow", width=12) + table.add_column("上涨趋势", justify="center", width=10) + table.add_column("价格突破", justify="center", width=10) + table.add_column("箱体运动", justify="center", width=10) + table.add_column("得分", justify="center", style="bold green", width=8) + + # 添加数据行 + for _, row in df_final.iterrows(): + # 根据得分设置颜色 + if row['得分'] >= 3: + score_style = "bold green" + elif row['得分'] >= 2: + score_style = "bold yellow" + else: + score_style = "bold red" + + # 设置趋势指标的颜色 + trend_color = "green" if row['上涨趋势'] == '是' else "red" + break_color = "green" if row['价格突破'] == '是' else "red" + box_color = "green" if row['箱体运动'] == '是' else "red" + + table.add_row( + f"[bold]{row['币种']}[/bold]", + f"[{trend_color}]{row['上涨趋势']}[/{trend_color}]", + f"[{break_color}]{row['价格突破']}[/{break_color}]", + f"[{box_color}]{row['箱体运动']}[/{box_color}]", + f"[{score_style}]{row['得分']}[/{score_style}]" + ) + + # 输出结果 + console.print("\n") + console.print(title_panel) + console.print(time_text, justify="center") + console.print("\n") + console.print(table) + + # 添加说明信息 + info_panel = Panel( + Text("📊 分析说明\n• 上涨趋势:EMA20 > EMA50 > EMA200\n• 价格突破:突破20日最高价\n• 箱体运动:价格在200日高低点范围内波动\n• 得分越高代表技术面越强势", + style="dim"), + title="💡 指标说明", + border_style="blue" + ) + console.print("\n") + console.print(info_panel) \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 116ad35..1a9d79c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: cryptoai-task: build: . container_name: cryptoai-task - image: cryptoai:0.0.18 + image: cryptoai:0.0.19 restart: always volumes: - ./cryptoai/data:/app/cryptoai/data diff --git a/requirements.txt b/requirements.txt index 4a88e74..0a57bef 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,6 +15,7 @@ python-multipart==0.0.9 email-validator==2.1.0 tencentcloud-sdk-python==3.0.1030 adata +tabulate # # 日志相关 # logging==0.4.9.6 # # 数据处理相关 diff --git a/test.py b/test.py index b23d29b..1379706 100644 --- a/test.py +++ b/test.py @@ -1,20 +1,5 @@ -from cryptoai.api.adata_api import AStockAPI -from cryptoai.api.binance_api import get_binance_api -import json -from time import sleep -from cryptoai.models.token import TokenManager -from cryptoai.utils.db_manager import get_db_context -from cryptoai.tasks.user import task_run from cryptoai.agents.crypto_agent import CryptoAgent if __name__ == "__main__": - CryptoAgent().start_agent() - - # data = get_binance_api().get_historical_klines( - # symbol="BTCUSDT", - # interval="1h", - # start_str="2024-01-01", - # end_str="2024-01-02", - # limit=100 - # ) - # print(data) + agent = CryptoAgent() + agent.start_agent() \ No newline at end of file