You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加密货币EMA指标告警程序开发报错求助:NameError问题

EMA加密货币Telegram告警程序修复

问题概述

需要为指定加密货币列表构建基于EMA指标的告警程序,当短周期EMA上穿长周期EMA时,通过Telegram推送消息。当前代码运行时出现NameError: name 'socket' is not defined错误,无法获取K线数据。

错误原因

  1. 重复定义了streamKline函数,导致后续函数覆盖了前期的websocket逻辑,但实际需要的是获取历史K线数据的功能
  2. 错误调用了不存在的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()

关键修改说明

  1. 替换数据源获取逻辑:删除无效的websocket函数,改用Binance的REST API获取K线数据,更适合新手调试使用
  2. 修复函数重复定义:删除重复的streamKline函数,重新命名为get_kline_data,明确功能定位
  3. 添加错误处理:对API请求和数据处理添加异常捕获,避免程序意外崩溃
  4. 避免重复告警:新增alerted_symbols集合,记录已推送过的货币对,防止同一金叉事件多次推送
  5. 优化API调用频率:在轮询结束后添加60秒暂停,符合Binance API的限流规则
  6. 美化告警消息:调整Telegram消息格式,内容更直观清晰

内容的提问来源于stack exchange,提问作者fox Des

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:50:40