开发Telegram行情告警Bot时遇DataFrame无法JSON序列化错误求助
解决TypeError: Object of type DataFrame is not JSON serializable问题
问题根源
你触发的错误是因为直接将pandas DataFrame对象传给了Telegram API的消息发送方法,而Telegram API要求发送的内容必须是可JSON序列化的基础类型(字符串、数字、列表等),DataFrame属于复杂对象,无法直接被JSON序列化。
解决方案
核心思路是:从DataFrame中提取告警所需的关键数据,格式化为字符串后再发送,不要传递整个DataFrame。
步骤1:提取并格式化告警数据
从KQ11指数数据中,只取最新一行的收盘价、3/5/10日均线值,拼接成易读的告警文本。示例代码片段:
# 假设你的DataFrame名为df,已计算好MA3、MA5、MA10均线列 latest_data = df.iloc[-1] # 获取最新一行数据 alert_text = f"""KQ11指数告警: 收盘价: {latest_data['Close']:.2f} 3日均线: {latest_data['MA3']:.2f} 5日均线: {latest_data['MA5']:.2f} 10日均线: {latest_data['MA10']:.2f} 当前收盘价高于均线,触发告警!"""
步骤2:修正Telegram消息发送逻辑
把原来传递DataFrame的代码,改成传递格式化后的字符串:
# 原来错误的写法(直接传DataFrame) # bot.send_message(chat_id=CHAT_ID, text=df) # 修正后的写法 bot.send_message(chat_id=CHAT_ID, text=alert_text)
完整修正示例代码
import FinanceDataReader as fdr from telegram import Bot import pandas as pd # 初始化Telegram Bot BOT_TOKEN = '你的BotToken' CHAT_ID = '你的ChatID' bot = Bot(token=BOT_TOKEN) # 获取KQ11指数数据 df = fdr.DataReader('KQ11', '2024-01-01') # 计算移动平均线 df['MA3'] = df['Close'].rolling(window=3).mean() df['MA5'] = df['Close'].rolling(window=5).mean() df['MA10'] = df['Close'].rolling(window=10).mean() # 检查告警条件 latest_data = df.iloc[-1] if (latest_data['Close'] > latest_data['MA3'] and latest_data['Close'] > latest_data['MA5'] and latest_data['Close'] > latest_data['MA10']): # 格式化告警文本 alert_text = f"""KQ11指数告警通知: 📈 收盘价: {latest_data['Close']:.2f} 📊 3日均线: {latest_data['MA3']:.2f} 📊 5日均线: {latest_data['MA5']:.2f} 📊 10日均线: {latest_data['MA10']:.2f} 当前收盘价已高于所有短期均线,请留意行情变化!""" # 发送告警消息 bot.send_message(chat_id=CHAT_ID, text=alert_text) else: print("未满足告警条件")
错误栈关键提示
错误栈中指向JSON序列化的环节(通常是json.dumps()调用),说明你的代码在发送消息时,把DataFrame作为了text参数的值,而Telegram Bot库会尝试将这个参数序列化为JSON格式发送给API,这就触发了类型错误。
内容的提问来源于stack exchange,提问作者Joshua Chung
相关产品推荐
相关产品推荐

