crypto.ai/cryptoai/tasks/token_selector.py
2025-06-10 15:52:20 +08:00

172 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)