问题描述
照搬一个MACD的简单例子,竟然出现类型错误,十分不解,征询高手指点。
macd_diff,macd_dea,macd_macd = MACD(security,check_date = context.current_dt, SHORT =12, LONG =26,MID = 9)
出错信息
if macd_diff >0 and macd_dea >0 and macd_diff > macd_dea :
TypeError: '>' not supported between instances of 'dict' and 'int'
整个函数
def handle_data(context,data):
security = g.security
macd_diff,macd_dea,macd_macd = MACD(security,check_date = context.current_dt, SHORT =12, LONG =26,MID = 9)
cash = context.portfolio.cash
if macd_diff >0 and macd_dea >0 and macd_diff > macd_dea :
order_value(security,cash)
log.info("买入股票 %s" % (security))
elif macd_diff < 0 and macd_dea < 0 and macd_diff < macd_dea and context.portfolio.positions[security].closeable_amount>0:
order_target(security,0)
log.info("卖出股票 %s" % (security))
解决方案
错误原因分析
您遇到的错误 TypeError: '>' not supported between instances of 'dict' and 'int' 是因为在 JoinQuant 聚宽平台的 jqlib.technical_analysis 库中,所有的技术分析指标函数(包括 MACD)返回的结果类型都是字典(dict),而不是直接的数值(int 或 float)。
为什么设计成返回字典?
因为聚宽的技术指标函数支持同时传入多只股票(即 security 参数可以是一个列表)。为了区分不同股票的指标值,函数返回的字典的键(key)是股票代码,值(value)才是对应的指标数值。
即使您只传入了一只股票代码,返回的依然是一个包含单个键值对的字典,例如:
{'000001.XSHE': 0.15}
因此,当您直接用 macd_diff > 0 时,实际上是在用一个字典和整数 0 进行比较,Python 不支持这种操作,从而抛出类型错误。
解决办法
要解决这个问题,您需要通过股票代码(security)作为键,从返回的字典中提取出具体的数值,然后再进行比较。
错误的代码:
if macd_diff > 0 and macd_dea > 0 and macd_diff > macd_dea:
正确的代码:
if macd_diff[security] > 0 and macd_dea[security] > 0 and macd_diff[security] > macd_dea[security]:
完整的修正后代码
以下是为您修正后的完整 handle_data 函数:
from jqlib.technical_analysis import MACD
def handle_data(context, data):
security = g.security
# 获取 MACD 指标,返回的是三个字典
macd_diff, macd_dea, macd_macd = MACD(security, check_date=context.current_dt, SHORT=12, LONG=26, MID=9)
# 从字典中提取具体的数值
diff_value = macd_diff[security]
dea_value = macd_dea[security]
cash = context.portfolio.available_cash
# 使用提取出的数值进行逻辑判断
if diff_value > 0 and dea_value > 0 and diff_value > dea_value:
order_value(security, cash)
log.info("买入股票 %s" % (security))
elif diff_value < 0 and dea_value < 0 and diff_value < dea_value and context.portfolio.positions[security].closeable_amount > 0:
order_target(security, 0)
log.info("卖出股票 %s" % (security))
总结提示
在 JoinQuant 中使用 jqlib.technical_analysis 库下的任何指标(如 KDJ, RSI, BOLL 等),请务必记住:返回值是字典,取值需加 [股票代码]。