ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【零依赖量化数据实战 #24】指数技术指标实战:MACD·MA·KDJ·BOLL

【零依赖量化数据实战 #24】指数技术指标实战:MACD·MA·KDJ·BOLL 【零依赖量化数据实战 #24】指数技术指标实战MACD·MA·KDJ·BOLL系列《零依赖量化数据实战》零依赖 · 纯 GET · 不 import 任何 SDK适用想用 Python 直接消费智兔已算好的指数技术指标MACD / MA / KDJ / BOLL一行出金叉死叉、多空头排列、超买超卖、开口收口信号的量化爱好者不依赖任何行情终端。1. 你将得到什么5 个官方接口的最小可用封装覆盖指数技术指标与指数历史分时两类需求GET /hz/history/macd/{index}/{period}指数 MACDDIF / DEA / MACD 柱GET /hz/history/ma/{index}/{period}指数多均线 MAGET /hz/history/kdj/{index}/{period}指数 KDJGET /hz/history/boll/{index}/{period}指数 BOLL上轨 / 中轨 / 下轨GET /hz/history/fsjy/{index}/{period}指数历史分时交易数据一套对字段名不敏感的信号函数上游返回里「DIF」可能叫dif/DIF「上轨」可能叫up/upper/boll_up用候选键命中不写死。用lt取最近 N 条即可在本地一行出 MACD 金叉/死叉、MA 多空头排列、KDJ 超买超卖、BOLL 开口收口。2. 端点语义表GET https://api.zhituapi.com/hz/history/macd/000001.SH/d?token你的tokenlt30 - 上证指数 日线 MACD最近 30 条 返回list每条含 DIF/DEA/MACD 类字段字段名随上游变 GET https://api.zhituapi.com/hz/history/ma/000001.SH/d?token你的tokenlt30 - 上证指数 日线 多均线 MAma5/ma10/ma20/ma60... GET https://api.zhituapi.com/hz/history/kdj/000001.SH/d?token你的tokenlt30 - 上证指数 日线 KDJK/D/J GET https://api.zhituapi.com/hz/history/boll/000001.SH/d?token你的tokenlt30 - 上证指数 日线 BOLLup/mid/low GET https://api.zhituapi.com/hz/history/fsjy/000001.SH/d?token你的tokenst20240101et20241231 - 上证指数 历史分时无 lt 参数按 st/et 取区间鉴权token走查询参数{index}为路径参数必须带市场后缀如000001.SH{period}为路径参数d日线、5/15/30/60分钟、w/m/y周/月/年线lt取最新 N 条st/et格式YYYYMMDD或YYYYMMDDhhmmss。3. 字段名不固定用候选键命中上游四类指标返回字段名都不统一中文/英文、大小写混用。统一用_hit_key候选键命中抽取对字段名不敏感def_hit_key(d,keys):ifnotisinstance(d,dict):returnNoneforkinkeys:ifkindandd[k]isnotNone:returnd[k]low{str(x).lower():xforxind.keys()}forkinkeys:klk.lower()ifklinlow:returnd[low[kl]]returnNone4. 核心模板函数importsys,requests BASEhttps://api.zhituapi.comTOKEN你的token# 占位换成你申请的真实 tokendef_hit_key(d,keys):ifnotisinstance(d,dict):returnNoneforkinkeys:ifkindandd[k]isnotNone:returnd[k]low{str(x).lower():xforxind.keys()}forkinkeys:klk.lower()ifklinlow:returnd[low[kl]]returnNonedef_get(path,paramsNone):pdict(paramsor{})p[token]TOKENtry:rrequests.get(f{BASE}{path},paramsp,timeout10)exceptExceptionase:returnNone,f网络异常{e}ifr.status_code!200:returnNone,f{r.status_code}{r.text.strip()[:140]}try:returnr.json(),NoneexceptException:returnNone,f非 JSON{r.text.strip()[:140]}deffetch_indicator(kind,index000001.SH,periodd,lt30):kind: macd|ma|kdj|boll。返回 (list_of_rows, err)。data,err_get(f/hz/history/{kind}/{index}/{period},{lt:lt})iferr:returnNone,err rowsdataifisinstance(data,dict):forkin(data,list,rows,items):ifisinstance(data.get(k),list):rowsdata[k];breakelse:rows[data]ifnotisinstance(rows,list):rows[rows]returnrows,None# 信号判断纯函数便于离线 selftestdefmacd_signal(rows):ifnotrowsorlen(rows)2:returnNonea,brows[-2],rows[-1]da_hit_key(a,[dif,DIF]);db_hit_key(a,[dea,DEA])ea_hit_key(b,[dif,DIF]);eb_hit_key(b,[dea,DEA])ifNonein(da,db,ea,eb):returnNoneifdadbandeaeb:returngolden# 金叉ifdadbandeaeb:returndead# 死叉returnholddefma_alignment(row):mas{}fork,vinrow.items():ifvisNone:continueklstr(k).lower()forpin(5,10,20,30,60,120,250):ifklin(fma{p},fma{p}_close,fma{p}close):try:mas[p]float(v)exceptException:passiflen(mas)2:returnmixvals[mas[p]forpinsorted(mas)]ifall(vals[i]vals[i1]foriinrange(len(vals)-1)):returnbull# 短周期在下、长周期在上 - 多头排列ifall(vals[i]vals[i1]foriinrange(len(vals)-1)):returnbear# 空头排列returnmixdefkdj_zone(row):j_hit_key(row,[j,J]);k_hit_key(row,[k,K])ifjisNoneandkisNone:returnNoneifjisnotNone:jfloat(j)ifj100:returnoverboughtifj0:returnoversoldifkisnotNone:kfloat(k)ifk80:returnoverboughtifk20:returnoversoldreturnneutraldefboll_band(row):up_hit_key(row,[up,upper,boll_up,BOLL_UP])mid_hit_key(row,[mid,middle,BOLL_MID,mb])low_hit_key(row,[low,lower,boll_low,BOLL_LOW])ifNonein(up,mid,low):returnNonereturnfloat(up),float(mid),float(low)defsummarize(rows,kind):ifnotrows:return 无数据lastrows[-1]ifkindmacd:returnf 最新 macd 信号{macd_signal(rows)}; DIF{_hit_key(last,[dif,DIF])}DEA{_hit_key(last,[dea,DEA])}ifkindma:returnf 最新 MA 排列{ma_alignment(last)}ifkindkdj:returnf 最新 KDJ 区{kdj_zone(last)}; K{_hit_key(last,[k,K])}D{_hit_key(last,[d,D])}J{_hit_key(last,[j,J])}ifkindboll:bboll_band(last)returnf 最新 BOLL up/mid/low{b}ifbelse 最新 BOLL 字段缺失return okdefselftest():# 合成数据仅逻辑自验非真实行情assertmacd_signal([{dif:0.10,dea:0.20},{dif:0.30,dea:0.25}])goldenassertmacd_signal([{dif:0.30,dea:0.20},{dif:0.10,dea:0.25}])deadassertma_alignment({ma5:1.0,ma10:1.1,ma20:1.2})bullassertma_alignment({ma5:1.2,ma10:1.1,ma20:1.0})bearassertkdj_zone({j:110,k:85})overboughtassertkdj_zone({j:-5,k:15})oversoldassertkdj_zone({j:50,k:50})neutralassertboll_band({up:1.3,mid:1.0,low:0.7})(1.3,1.0,0.7)assertboll_band({BOLL_UP:1.3,BOLL_MID:1.0,BOLL_LOW:0.7})(1.3,1.0,0.7)print(selftest PASS)if__name____main__:iflen(sys.argv)1andsys.argv[1]--selftest:selftest()else:forkindin(macd,ma,kdj,boll):rows,errfetch_indicator(kind)print(f{kind}- ({rows},{err}))ifrows:print(summarize(rows,kind))data,err_get(/hz/history/fsjy/000001.SH/d,{st:20240101,et:20241231})print(ffsjy - ({data},{err}))5. 代码自验结果离线selftest合成数据仅验证逻辑不含任何真实行情selftest PASS联网实测占位 token真实返回--- 联网实测占位 token预期 404 102:Licence证书不存在--- macd - (None, 404 102:Licence证书(你的token)不存在) ma - (None, 404 102:Licence证书(你的token)不存在) kdj - (None, 404 102:Licence证书(你的token)不存在) boll - (None, 404 102:Licence证书(你的token)不存在) fsjy - (None, 404 102:Licence证书(你的token)不存在)把TOKEN 你的token换成你申请的真实 token上述函数即可打印指数 MACD、MA、KDJ、BOLL 技术指标数据。本文未编造任何真实数值。6. 坑与注意事项102 不代表路径对404 102是「证书不存在」鉴权先于路由路径合法与否要靠客户端白名单自查不能凭报错反推接口可用。指数代码必须带市场后缀写000001会路由错误必须000001.SH深证成指399001.SZ、创业板指399006.SZ同理。lt取最近 N 条技术指标接口用lt最新条数控制返回量省略则拉全历史fsjy历史分时没有lt用st/et区间。字段名随上游变「DIF」可能dif/DIF「上轨」可能up/upper/boll_up务必用候选键命中别硬写英文键。信号是「本地算」不是「接口给」接口只给指标序列金叉/死叉/排列/超买超卖这些判断都在macd_signal/ma_alignment/kdj_zone里本地完成可按需改写阈值。7. 小结与下篇预告本篇把「指数 MACD / MA / KDJ / BOLL 历史分时」拧成了 5 个零依赖接口的最小封装重点解决了指数代码带市场后缀、lt取最近 N 条、指标字段名中英文混用三个坑配候选键命中即可一行出信号。下一篇计划写 #25《北交所技术指标与基本面》讲解如何用官方接口拉取北交所股票的技术指标MACD·MA·KDJ·BOLL与基本面数据股本、十大股东、流通股东、财务主要指标把「北交所」也接进零依赖工作流。8. 免责声明本文仅演示公开数据接口的用法所有代码示例均以占位 token 自验未含任何真实数据文中合成数据仅为逻辑自验用途不构成投资建议亦不承诺收益。
返回列表