加密货币EMA指标告警程序开发报错求助:NameError问题
EMA加密货币Telegram告警程序修复
问题概述
需要为指定加密货币列表构建基于EMA指标的告警程序,当短周期EMA上穿长周期EMA时,通过Telegram推送消息。当前代码运行时出现NameError: name 'socket' is not defined错误,无法获取K线数据。
错误原因
- 重复定义了
streamKline函数,导致后续函数覆盖了前期的websocket逻辑,但实际需要的是获取历史K线数据的功能 - 错误调用了不存在的
socket.streamKline方法,未正确对接Binance的数据源
修复后的完整代码
配置文件(config.py)
### configuration details TELEGRAM_TOKEN = '你的Telegram Bot Token' # telegram bot token TELEGRAM_CHANNEL = '你的频道ID' # channel id INTERVAL = '1m' # binance time interval SHORT_EMA = 7 # short interval for ema LONG_EMA = 21 # long interval for ema
主程序代码
import requests import talib import time import numpy as np from config import TELEGRAM_TOKEN, TELEGRAM_CHANNEL, INTERVAL, SHORT_EMA, LONG_EMA # 监控的加密货币对列表 SYMBOLS = [ "ETHUSDT", "BTCUSDT", "ATOMUSDT", "BNBUSDT", "FTMBUSD", "ENJUSDT", "WAXPUSDT" ] # 发送告警到Telegram频道 def send_message(message): url = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage?chat_id={TELEGRAM_CHANNEL}&text={message}&parse_mode=markdown" try: res = requests.get(url) res.raise_for_status() print(f"消息发送成功: {message}") except Exception as e: print(f"消息发送失败: {e}") return res # 从Binance REST API获取K线数据 def get_kline_data(symbol): # Binance REST API接口,获取最近300条K线数据 url = f"https://api.binance.com/api/v3/klines?symbol={symbol}&interval={INTERVAL}&limit=300" try: response = requests.get(url) response.raise_for_status() data = response.json() # 提取收盘价,转换为numpy数组 close_prices = np.array([float(kline[4]) for kline in data]) return close_prices except Exception as e: print(f"获取{symbol} K线数据失败: {e}") return None def main(): print("EMA告警程序启动...") # 记录已发送告警的货币对,避免重复推送 alerted_symbols = set() while True: for symbol in SYMBOLS: close_prices = get_kline_data(symbol) if close_prices is None or len(close_prices) < LONG_EMA: time.sleep(1) continue # 计算短周期和长周期EMA ema_short = talib.EMA(close_prices, SHORT_EMA) ema_long = talib.EMA(close_prices, LONG_EMA) # 确保有足够的EMA数据点 if len(ema_short) < 2 or len(ema_long) < 2: time.sleep(1) continue # 获取上一根和当前的EMA值 prev_short = ema_short[-2] prev_long = ema_long[-2] curr_short = ema_short[-1] curr_long = ema_long[-1] # 检测金叉(短EMA上穿长EMA) if curr_short > curr_long and prev_short <= prev_long: if symbol not in alerted_symbols: message = f"🚀 {symbol} 出现金叉!\n{SHORT_EMA} EMA 上穿 {LONG_EMA} EMA" send_message(message) alerted_symbols.add(symbol) # 当EMA再次死叉时,移除告警标记,允许下次金叉推送 elif curr_short < curr_long and prev_short >= prev_long: if symbol in alerted_symbols: alerted_symbols.remove(symbol) time.sleep(0.5) # 每次轮询所有货币对后,暂停一段时间,避免触发Binance API限流 time.sleep(60) if __name__ == "__main__": main()
关键修改说明
- 替换数据源获取逻辑:删除无效的websocket函数,改用Binance的REST API获取K线数据,更适合新手调试使用
- 修复函数重复定义:删除重复的
streamKline函数,重新命名为get_kline_data,明确功能定位 - 添加错误处理:对API请求和数据处理添加异常捕获,避免程序意外崩溃
- 避免重复告警:新增
alerted_symbols集合,记录已推送过的货币对,防止同一金叉事件多次推送 - 优化API调用频率:在轮询结束后添加60秒暂停,符合Binance API的限流规则
- 美化告警消息:调整Telegram消息格式,内容更直观清晰
内容的提问来源于stack exchange,提问作者fox Des
相关产品推荐
相关产品推荐

