全部
文章&策略
学习干货
问答
官方
用户头像sh_***174w0d
2026-08-14 发布
引言:告别指标冲突,寻找交易的“黄金搭档” 在二级市场的博弈中,多数散户常年处于一种“指标内耗”的怪圈:单纯盯着MACD,往往等行情拉升了一大截才看到信号,深受“指标滞后”之苦;转身去追灵敏的KDJ,却又被日线级别频繁的“假金叉”反复收割,在不断的追涨杀跌中损耗本金。 如何破局?作为职业选手,我们从不寄希望于单一指标的“神谕”,而是追求逻辑的共振。MACD与KDJ的结合,在业内被尊称为“龙虎组合”。这套战法的底层逻辑在于:用MACD定性趋势的“大潮”,用KDJ捕捉波动的“浪花”。当稳健与灵敏达成一致,才是真正高胜率的财富密码。 指标真相:稳健趋势与灵敏波动的完美互补 要驾驭这套组合,你必须理解两者截然不同的“性格”。我常说,交易就是在大趋势中找小买点。 ●MACD(趋势之虎): 它是趋势定性的“定海神针”。优势在于过滤噪音,提供极高可靠性的中长期方向。缺点是身重影慢,反馈严重滞后。 ●KDJ(灵敏之龙): 它是盘面感知的“先锋官”。优势是反应极其敏捷,能精准切入短期拐点。缺点是定力不足,容易在震荡行情中频繁发出误导信号。 “两个指标优缺点正好互补,配合使用能实现一加一大于2的效果。” 这种互补,本质上是“空间”对“时间”的降维打击。 顶级入场信号:双指标共振金叉 当“趋势之虎”开始抬头,“灵敏之龙”顺势起飞,这就是职业选手中最推崇的入场时机。 实战环境: MACD双线当前运行在零轴下方(处于筑底或超跌反弹区)。 触发点(必须按顺序确认): 1.****MACD“拐头”**金叉: 注意!不是简单的金叉,而是快线必须先行拐头向上**并穿过慢线。这个“钩子”动作代表大方向的下杀动能衰竭,趋势存在强烈的反转可能。 2.KDJ同步共振: 在MACD快线钩头向上的同时,KDJ也同步走出金叉。 量化分析: 这是极其罕见的优质进场信号。MACD的拐头为行情定了性,排除了KDJ的随机波动;而KDJ的金叉则为MACD锁定了进场点位。这种共振一旦形成,后续通常伴随着爆发性的拉升行情。 想要批量回测 MACD 与 KDJ 共振信号、简化指标复盘流程,可以参考 9db交割单 工具提供的轻量化指标分析工具。 避坑指南:为什么MACD零轴下的KDJ金叉不可盲信? 这是散户亏损的核心重灾区。很多新手看到KDJ金叉就冲进去,结果往往是“接盘在半山腰”。 底层逻辑:大趋势压制小波动 当MACD****双线长期压制在零轴下方,且完全没有拐头向上的动能时,此时的KDJ金叉就是典型的“诱多陷阱”。 专家警示: 在这种背景下,KDJ的金叉仅仅代表股价在崩塌过程中的“短期虚假修复”或技术性抽血。由于MACD作为趋势主轴依然向下,这种微弱的反弹根本无力扭转大局。在职业选手的眼中,这种没有“大势”支撑的信号,入场风险极高,属于典型的“火中取栗”。 果断离场:卖在深调前,这才是职业选手的逃顶本领 在市场中,会买的是徒弟,会卖的才是师傅。利用“龙虎组合”,我们能精准识别深度调整的开端。 离场场景设定(无条件执行): 场景一:同步共振死差。 无论当前股价多高,一旦MACD与KDJ在同一区间同步形成死差,必须果断卖出,哪怕卖错也要先出来,绝不心存幻想。 场景二:弱势区域死差。 如果MACD本身就处于零轴下方的弱势区,此时KDJ哪怕单独走出死差,也必须及时离场。 行动建议: 这两个信号的出现,大概率预示着市场将开启一轮深度调整**。在风险面前,职业选手的第一本能永远是保住本金,而非贪恋最后那点碎肉。 总结与反思:在投资路上少踩认知的坑 交易不是赌博,而是基于“资金运行逻辑”的深度拆解。通过MACD与KDJ的组合,我们学会了利用“大趋势”为“小波动”定性,在杂乱无章的盘面中,剥离出真正的确定性。 最后留给各位一个启发性的思考: 在你的交易系统中,你是倾向于听从“灵敏”的警报去抢跑,还是愿意多一点耐心,等待“稳健”的趋势确认? 理解指标背后的哲学冲突与共生,是你从亏损散户迈向成熟投资者的必经之路。
浏览23
评论0
收藏0
用户头像sh_***174w0d
2026-08-14 发布
引言:揭开“成交量”的迷雾 “新手看价,老手看量。”在波谲云诡的股市中,很多投资者最感到困惑的莫过于:为什么有时候放量反而大跌,缩量却能一路长虹?这种常见的“量价背离”往往让缺乏经验的股民在关键时刻掉队,甚至在高位站岗。 其实,成交量是主力在盘面上唯一无法隐藏的真实足迹。它是识别突破真伪、洞察主力意图的终极底牌。想要从“韭菜”进阶为专业投资者,就必须明白成交量的核心价值在于关键价位的确认,而非单纯数字的增减。 今天,我将结合多年的实战经验,把复杂的成交量逻辑浓缩为四句口诀,带你精确认清市场的起伏真相。 口诀一:突破前后看量,好钢要用在刀刃上 在面临压力位突破的关键时刻,成交量的分布必须符合严密的先后逻辑。 “好钢要用在刀刃上。” 深度分析: 所谓的“刀刃”,就是股价临近前期高点等关键压力区间的那个点位。当股价冲击该区间时,理想的状态是成交量持续递增。这不仅仅是为了消化上方的套牢盘,更是为了在充分换手中“吸引新进看多资金”,形成合力。 一旦放量冲破“刀刃”,后续如果走出“缩量上涨”的行情,反而是极佳的信号。为什么突破后缩量更好?因为这意味着在关键位已经完成了充分的筹码交换,该位置的抛压已大幅减轻,多头资金达成了高度的共识。这种“资金共识统一”的状态,预示着上涨趋势具备极强的延续性。 但跨过这道线之后,真正的审判才刚刚开始。很多投资者往往就在这个阶段被主力*“洗”*了出去。 口诀二:突破后的量能审判——缩量延续,放量警惕 股价跨越压力位后,成交量的表现就像是一面照妖镜,能立刻显现出涨势的成色。 **●**缩量上涨还能涨: 股价创出新高但量能并未同步放大,甚至持续缩量。这说明上方几乎没有抛压,筹码高度锁定。这种形态往往代表个股的短线爆发力最强。 **●**放量上涨多观望: 如果是在底部启动区域,放量是健康的。但若股价已在拉升后的高位再次爆出巨量,这往往是“动能衰竭”或“筹码松动”的信号。这可能是主力在进行高位洗盘,甚至是变相出货。此时切勿盲目追高,短期大概率会陷入震荡甚至直接回落。 **●**放量滞涨要撤退: 股价在高位维持或波动,成交量放出巨量,股价却始终无法刷新阶段新高。这是典型的量价背离,属于高位见顶的危险信号。遇到这种“换手虽大却不涨”的情况,必须果断避险。 口诀三:真假突破的试金石——无量突破多为假 很多投资者看到“创新高”就兴奋,却忽略了支撑新高的基石是否稳固。 核心逻辑: 关键压力位必须匹配对应的量级。 这是一个硬性的能量守恒原则。 如果个股在冲击前期高点时,没有放出近期的高量,而是表现得“轻轻松松”,无量就创出了新高,这种突破极度危险。这种“轻松”往往意味着主力并没有通过真金白银去消化阻力,根基不稳的突破大都会演变成冲高回落的陷阱。只有在抵达关键位时伴随同步放量,一举冲破阻拦,才是被市场认可的“有效真突破”。 口诀四:警惕无端放量陷阱——非关键位的放量必有猫腻 主力经常利用成交量的放大来人为制造热度,从而引诱散户入局。 要点阐述: 我们要坚持一个基本原则:放量应当出现在阻力位。如果远离压力位却莫名其妙地放量,那么**“无端放量必有猫腻”**。 在下跌趋势中,股价如果还没触及关键阻力区,就突然收出几根伴随巨量的大阳线,这通常不是反转。这种行为往往是因为“多头力度偏弱”,主力不得不通过“自导自演”的对倒行为来制造诱多陷阱。只要放量出现在无关紧要的非关键价位,就必须防范主力在大规模砸盘前的最后“闪存”。 结语:从认知误区走向盈利逻辑 学习成交量的本质,是为了让我们从单纯的“看数字”进阶到“看逻辑”。成交量的价值不在于它的大小,而在于它是否出现在了该出现的地方。只有理解了量价背后的资金博弈,你才能在市场的迷雾中,一眼识别出哪些是真机会,哪些是温柔的陷阱。 行动号召: 回顾你最近的一次买入操作,那次突破时的成交量是否符合“好钢用在刀刃上”的逻辑?如果当时出现了“无端放量”,你是否成功避开了陷阱?欢迎在复盘时重新审视。
浏览26
评论0
收藏0
用户头像sh_****559rtx
2026-08-14 发布
在同花顺量化社区,我们经常看到做外汇的朋友讨论策略回测与实盘不一致,尤其是涉及跨周末、跨交易日的品种。我们团队也在这个问题上花了不少时间,最终定位到Tick数据边界处理。本文分享我们的处理方案,希望对同样用实时外汇API做量化的朋友有帮助。 一、回测结果漂移的根源 我们在做外汇行情数据处理时,遇到过这样一个问题:同一套交易策略,在不同时间段测试时结果差异明显。刚开始我们一直在检查指标计算逻辑,甚至重新验证了策略参数,但后来发现真正影响结果的是Tick数据跨交易日拼接的问题。 外汇市场不像股票市场一样有明确的每日开盘和收盘,但行情数据在不同交易时段之间依然存在明显变化。特别是在周末休市之后重新开盘,或者欧美市场交接时段,价格可能出现快速变化。如果实时外汇API获取的Tick数据没有正确处理交易日边界,就容易导致K线异常、指标偏差,甚至影响策略判断。 二、行情数据在交易日边界的表现 很多时候,Tick数据看起来只是简单的一条条报价记录,只需要按照时间排序即可。但真正用于分析时,时间连续并不代表行情连续。例如周五纽约市场结束后,到周一亚洲市场重新开盘,中间会存在较长时间没有交易数据。新的交易周开始时,市场可能因为消息、流动性变化等因素出现价格跳空。 这时候如果程序直接把两个时间段的数据连接起来,可能会把周五最后价格和周一第一个价格之间的变化,当成正常行情波动。 时间阶段 数据特点 周五收盘前 流动性逐渐降低,Tick减少 周末期间 没有有效交易数据 周一开盘后 新报价出现,可能产生跳空 这种情况对于分钟K线影响还比较明显,如果进一步计算均线、波动率或者趋势指标,误差会继续放大。回测中如果出现这种误差,策略的收益曲线和回撤都会被扭曲。 三、我们如何修复数据边界 我们现在处理外汇Tick数据时,会先解决时间问题,再进行价格计算。不同实时外汇API返回的时间字段可能存在差异,有些使用UTC时间,有些使用交易市场时间。如果直接混合使用,很容易在跨日时出现判断错误。 比较稳定的方式是统一时间标准。接收到Tick数据后,先转换成UTC格式保存,生成K线或者分析行情时,再根据需要转换成目标时区。这样做可以避免夏令时变化、地区时间差异对数据造成影响。 按交易日划分数据再生成K线,是我们目前比较稳定的做法。以前我们会直接把所有Tick放在一起计算周期数据,后来发现这种方式在跨交易日场景下容易出问题。现在的流程是: 对Tick时间进行统一格式转换; 按UTC时间排序; 判断日期变化; 标记新的交易日; 分别生成对应周期K线。 这样可以让每个交易日的数据保持独立,避免隔夜价格变化影响当天行情统计。对于回测来说,这意味着每个交易日的K线起点不会包含前一天的隔夜波动,信号也更干净。 四、实时Tick接入与时间转换 在实时行情场景中,我们更倾向于使用WebSocket获取数据。相比不断请求接口,WebSocket更适合连续变化的Tick行情。以 AllTick API 为例,我们会通过WebSocket订阅实时行情,接收到数据后先处理时间字段,再进入K线计算流程。 import websocket import json from datetime import datetime, timezone def on_message(ws, message): data = json.loads(message) if data.get("symbol") == "EURUSD": timestamp = data.get("timestamp") utc_time = datetime.fromtimestamp( timestamp / 1000, tz=timezone.utc ) price = data.get("price") print( "time:", utc_time, "price:", price ) def on_open(ws): request = { "action": "subscribe", "symbol": "EURUSD", "type": "tick" } ws.send(json.dumps(request)) ws = websocket.WebSocketApp( "wss://api.alltick.co/ws", on_open=on_open, on_message=on_message ) ws.run_forever() 这段代码主要处理的是时间标准化,而不是简单获取价格。只有保证每条Tick的时间位置准确,后续生成的K线和策略信号才更可靠。 五、回测与实盘都要注意的细节 实际运行过程中,有几个问题比较容易被忽略: 周末数据间隔需要单独判断。周五最后一条Tick和周一第一条Tick之间的时间差很大,这并不是普通行情波动。 交易时段不同,Tick数量也会明显变化。欧美活跃时间行情更新频繁,而部分时段数据较少,如果直接计算短周期指标,可能会产生异常结果。 数据缺失也是需要关注的问题。如果某段时间没有收到Tick,程序需要判断这是市场低活跃,还是数据连接异常。 六、社区小结 处理外汇行情数据一段时间后,我们发现真正影响分析结果的,往往不是复杂的指标公式,而是这些基础数据细节。实时外汇API提供的是连续行情数据,但如何理解这些数据,需要结合市场交易时间、时间戳规则以及交易日划分。跨交易日拼接并不是简单地把数据连接起来。提前做好时间统一、交易日判断和异常间隔检测,才能让后面的回测和实时分析更加稳定。对于外汇量化场景来说,隔夜跳空属于市场正常现象,关键在于数据处理方式是否能够正确识别它。希望这篇分享对大家的回测和实盘有所帮助。
浏览18
评论0
收藏0
用户头像sh_**772oqg
2026-08-14 发布
一、研究背景与通用数据管线固有缺陷 在多标的 A 股策略回测、日内高频交易模型研发过程中,多数研究者搭建的 Tick 采集管线仅聚焦正常交易时段数据采集,未针对交易所异动临停场景设计适配逻辑。当个股因短期价格异常波动触发临时停牌,实时 Tick 数据流会直接中断;待标的复牌,现有程序缺少标准化判定逻辑,无法自动锁定行情接口恢复推送的精确时间边界,进而衍生出多重模型失真问题:复牌集合竞价首批 Tick 漏采集、批量回测数据集出现持续性时序断层、自动化交易模型误判市场无成交而触发风控拦截。 早期主流处理方式为人工对照行情终端记录时间戳,但人工记录存在数秒级时序偏移,无法满足高频量化、高精度历史仿真对时序对齐的硬性要求。基于多套云端采集管线、离线回测项目的复盘调试经验,本文梳理一套无人工干预的自动化时点解析框架,适用于各类自建量化数据采集与策略仿真体系。 在多组数据源对比测试后,总结通用行情接口在临停周期内存在三类结构性数据短板,也是复牌恢复时点识别失真的核心诱因: 停牌周期无独立交易状态标识:接口仅停止推送成交数据,未通过专用字段区分 “交易所规则停牌” 与 “网络链路中断”,模型无法自主判断数据流中断成因; 缺失交易所官方复牌基准时间戳:普通接口仅返回单笔成交报价时间,不配套交易所统一发布的复牌基准时序,长期回测会产生系统性时序基准偏移; 多标的并行采集时序无序:批量监控数十只 A 股标的时,各品种临停、复牌时点相互错开,通用接口无全局时序排序机制,批量采集程序极易出现数据前后错位、样本匹配失效。 为消除该类时序识别偏差,本次研究统一作为底层行情数据源,接口原生输出交易所标准化交易状态标签与毫秒级官方时间戳,从数据源头补齐临停场景所需的识别元数据。 WebSocket 多标的订阅基础可运行代码 import websocket import json # 内存缓冲区:存储个股Tick时序、官方时间戳、交易状态 tick_buffer = {} def msg_receive(ws, raw_info): tick_info = json.loads(raw_info) stock_code = tick_info.get("symbol") trade_ts = tick_info.get("official_ts") market_status = tick_info.get("trade_state") tick_buffer[stock_code] = {"ts":trade_ts,"state":market_status} def sub_init(ws): sub_body = json.dumps({"action":"subscribe","symbols":["600030","000001"],"type":"tick"}) ws.send(sub_body) if __name__ == "__main__": ws_link = websocket.WebSocketApp("wss://api.alltick.co/ws",on_open=sub_init,on_message=msg_receive) ws_link.run_forever() 该采集脚本算力占用极低,可长期部署于云端算力节点持续运行,依托trade_state字段区分停牌、复牌状态,通过official_ts字段锁定行情推送恢复基准时点,是多标的时序采集体系的基础底层模块。 二、双层标准化校验判定模型(适配时序存储与策略仿真架构) 依托行情源内置标准化元数据字段,构建轻量化双层时序校验逻辑,全程无需人工介入,可直接嵌入 Tick 采集、离线批量回测、自动化交易仿真全链路: 第一层:交易状态字段基础判定规则 持续解析 Tick 数据包内trade_state标识,当字段切换为resume_trade的首条 Tick 附带的official_ts,即为交易所官方定义的行情推送恢复基准时间;若字段长期保持suspend,则判定标的处于临停静默周期,跳过复牌时序校验流程。 第二层:滑动窗口时序连续性二次校验 全部 Tick 时间戳统一写入时序数据库持久存储,配置固定长度滑动窗口做交叉校验:仅当复牌基准时点后连续捕获 3 笔无时间间隙的完整 Tick 样本,才判定行情数据流完全恢复推送,过滤复牌瞬时补发的延迟历史零散数据,规避模型误判恢复时点。 整套判定逻辑计算开销极小,不会占用大量算力资源,可分层嵌入数据采集预处理模块、回测数据清洗模块、实盘模拟风控模块,适配不同复杂度的量化研究任务。 三、动态时点识别框架在量化体系中的两大核心落地价值 依托双层校验逻辑实现的临停恢复时点自动识别体系,主要解决两类量化研究场景的核心痛点,优化回测真实性与策略运行稳定性: 日内高频自动化交易仿真优化 模型读取精准复牌基准时间后,自动解除临停阶段触发的风控限制,完整捕获复牌集合竞价 Tick 样本,完整捕捉短线资金异动特征;同时在停牌静默期暂停冗余循环接口请求,降低带宽资源消耗与接口调用配额占用。 多标的批量离线回测数据标准化治理 批量历史回测执行阶段,程序依据复牌官方时间戳自动分割临停区间与常规交易区间,向时序日志库写入区间分界标记,彻底修复异动停牌带来的数据时序断层,大幅缩小仿真结果与真实市场运行状态的偏差,提升回测结论参考价值。 四、量化研究落地总结 完成整套临停时序识别体系落地后可得出客观结论:多数量化研究者研发重心集中于价格、成交量等显性行情指标,容易忽略临停、复牌这类特殊交易时段的数据治理架构设计。若底层行情接口缺少标准化交易状态标识、交易所基准时间戳,很难通过轻量代码实现稳定、无偏差的复牌时点自动识别。 将带完整元数据的行情接口与双层时序校验架构结合,可完全替代人工时序记录操作,系统性修复异动停牌引发的数据失真问题,同步提升高频策略仿真、多标的批量回测两类研究场景的数据精度与程序长期稳定运行能力。 研究交流提问 各位在搭建多标的 A 股时序采集管线、开展大规模批量回测实验时,是否遇到过个股临停后复牌时序识别偏差、批量标的数据错位、自动化模型误触发风控等工程问题?欢迎交流对应的排查思路与管线优化方案。
浏览24
评论0
收藏0
用户头像sh_*219t3e
2025-09-26 发布
大家好,我想和大家分享一个我最近开发的项目——一款面向量化交易的 AI 智能助手工具网站。它可以帮助大家快速生成高质量、可直接复制运行的量化策略代码,无论你是量化小白还是策略开发者,都能从中受益。 核心亮点: 1.多平台支持:目前已支持 PTrade、QMT、miniQMT、聚宽等,并计划不断扩展更多平台。 2.策略生成高效:用户只需选择平台并输入策略想法,AI 即可生成可运行的量化策略代码。 3.快速入门与优化: • 对量化小白:轻松生成可直接运行的策略,快速上手交易。 • 对策略开发者:帮助完善、优化已有策略,节省开发时间。 • 对文档需求者:可作为量化平台的 API 文档问答机器人,方便查询和使用。 4.业内首创:这是首个面向多平台的量化交易 AI 助手,解决了现有 Deepseek 或 Trae 等 AI 工具因缺乏平台知识库而生成代码无法运行的问题。 使用方式:登录 → 选择你使用的平台 → 输入策略想法 → 生成可运行的策略代码。 我希望这个工具能帮助大家更高效地进行策略开发和量化交易,也欢迎大家在帖子里分享使用体验和建议。 网站链接:https://iris.findtruman.io/ai/tool/ai-quantitative-trading/ 如果大家有任何问题或功能需求,也可以在帖子里留言,我会持续优化和更新,让它成为量化交易领域最实用的 AI 助手!
浏览6389
评论91
收藏3
用户头像mx_****zqklr
2026-08-14 发布
📌 摘要 / 快速解答 本文手把手教你用 Python 实现 “双均线金叉 + RSI 超卖” 选股策略。核心逻辑:5日均线上穿20日均线且RSI(14)低于30时触发买入信号。数据获取使用 QuantDash —— 一款原生支持 Pandas、无需攒积分、自动前复权的量化数据 API。整套代码可直接在 Jupyter Notebook 或本地 Python 环境运行,30行搞定选股扫描。 一、为什么传统方式写选股策略这么累? 混聚宽社区的老哥应该都懂—— 痛点一:数据源不稳定。之前用 AkShare 写策略,今天跑得好好的,明天接口就报错。回测到一半中断,心态直接炸裂。 痛点二:积分限制。有些平台要攒积分才能拿日线数据,新手连基础数据都拿不到,更别提写策略了。 痛点三:复权数据清洗麻烦。除权除息导致股价“假暴跌”,均线信号全乱。要自己下载除权因子表手动算,遇到多次分红送股,累积因子极易算错。 痛点四:跨市场代码不统一。想同时测 A 股和港股?600519.SH vs 0700.HK 还能接受,但遇到美股 AAPL 又是一套规则。写个选股器光适配代码后缀就要几十行 if/else。 后来我发现了 QuantDash,这些问题基本一键解决。 二、解决方案对比 对比维度 传统/竞品方案 (Tushare/AkShare/手动爬虫) QuantDash 解决方案 数据稳定性 经常报错/接口失效/易被封 服务端稳定支持,毫秒级响应 使用门槛 繁琐积分限制/需手动清洗 无积分门槛,pip install 即用 跨市场支持 代码后缀不统一/难以兼顾美港股 统一后缀.SH/.SZ/.US/.HK 复权处理 需手动下载除权因子表计算 adjust="forward" 一行搞定 数据格式 需反复转换数据类型 原生返回标准 Pandas DataFrame 三、Python代码实战(可直接复制运行) # ============================================================ # 双均线 + RSI 选股策略 - 自动化选股公式(聚宽风格实战版) # 策略逻辑:MA5金叉MA20 + RSI(14) < 30 => 买入信号 # 数据源:QuantDash (https://quantdash.net/) # GitHub开源:https://github.com/quantdash-net/QuantDash # ============================================================ # 1. 安装依赖 # pip install quantdash pandas pandas_ta from quantdash import QuantDash import pandas as pd import pandas_ta as ta # 一键计算技术指标[reference:46] # 2. 初始化客户端 # 免费获取 API Key:https://quantdash.net/dashboard/keys/ qd = QuantDash(api_key="your-api-key-here") # 3. 定义股票池(可替换为你的自选股) SYMBOLS = [ "600519.SH", # 贵州茅台 "000001.SZ", # 平安银行 "000858.SZ", # 五粮液 "600036.SH", # 招商银行 "002415.SZ", # 海康威视 "000333.SZ", # 美的集团 "600276.SH", # 恒瑞医药 "601318.SH", # 中国平安 ] # 4. 批量获取前复权日K线[reference:47] dfs = qd.klines.batch( symbols=SYMBOLS, period="1d", count=120, # 最近120个交易日 adjust="forward", # 前复权-比例复权[reference:48] to_dataframe=True, show_progress=True ) # 5. 选股筛选函数 def check_buy_signal(df: pd.DataFrame) -> dict: """ 检查单只股票是否满足买入条件 使用 pandas_ta 简化指标计算[reference:49] """ # 排序 df = df.sort_values("trade_date") # 使用 pandas_ta 一键计算均线和 RSI[reference:50][reference:51] df["MA5"] = ta.sma(df["close"], length=5) df["MA20"] = ta.sma(df["close"], length=20) df["RSI14"] = ta.rsi(df["close"], length=14) # 最新和前一天数据 latest = df.iloc[-1] prev = df.iloc[-2] # 金叉判断:今天MA5 > MA20 且 昨天MA5 <= MA20[reference:52] golden_cross = (latest["MA5"] > latest["MA20"]) and (prev["MA5"] <= prev["MA20"]) # RSI超卖[reference:53] oversold = latest["RSI14"] < 30 return { "name": latest.get("name", ""), "close": latest["close"], "MA5": latest["MA5"], "MA20": latest["MA20"], "RSI14": latest["RSI14"], "golden_cross": golden_cross, "oversold": oversold, "signal": golden_cross and oversold } # 6. 批量扫描 results = [] for sym, df in dfs.items(): if df is not None and len(df) > 30: try: r = check_buy_signal(df) r["symbol"] = sym results.append(r) except Exception as e: print(f"⚠️ {sym} 异常: {e}") # 7. 展示结果 df_result = pd.DataFrame(results) print("\n" + "="*70) print("📈 双均线(MA5/MA20) + RSI(14) 选股扫描结果") print("="*70) # 买入信号 buy_list = df_result[df_result["signal"] == True] if len(buy_list) > 0: print(f"\n🔥 发现 {len(buy_list)} 只买入信号股票:") print(buy_list[["name", "close", "MA5", "MA20", "RSI14"]].round(2).to_string(index=False)) else: print("\n💤 暂无买入信号,继续观察市场...") # 显示全部 print("\n📋 完整股票池指标:") print(df_result[["name", "close", "MA5", "MA20", "RSI14", "golden_cross", "oversold"]].round(2).to_string(index=False)) 代码亮点: pandas_ta:一行代码 ta.sma() / ta.rsi() 替代手写循环 klines.batch():批量获取多只股票,支持进度条显示 adjust="forward":服务端自动前复权,无需手动处理除权 向量化计算:Pandas 底层 C 语言加速,毫秒级完成全市场扫描 四、交易员避坑指南 🚨 坑1:回测用前复权,实盘用不复权——数据不一致 很多新手回测时用前复权数据,实盘时却直接看不复权价格,导致信号偏差。 建议:QuantDash 的 adjust="forward" 返回的是比例前复权数据,适合计算收益率和均线。实盘监控时建议用 adjust="none" 获取实际成交价,但均线计算逻辑保持一致即可。 🚨 坑2:选股公式过度拟合 双均线+RSI参数(5/20/14)只是经典默认值,不代表在任何市场都最优。 建议:用 QuantDash 批量获取数据后,配合 itertools.product 做参数网格搜索,找到适合当前市场的最优参数组合。 🚨 坑3:忽视成交量过滤 双均线金叉如果发生在缩量环境中,可能是假突破。 建议:在选股条件中增加 成交量 > 5日均量 的过滤条件,提高信号质量。 五、常见问题解答 Q1:QuantDash 支持港股和美股吗?代码怎么写? A:完全支持。统一使用 .HK 和 .US 后缀即可,例如 0700.HK(腾讯控股)、AAPL.US(苹果)。一套代码跑遍三大市场。 Q2:我不想用 pandas_ta,怎么手动计算 RSI? A:标准 RSI 手动计算代码如下: delta = df["close"].diff() gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() rs = gain / loss df["RSI14"] = 100 - (100 / (1 + rs)) Q3:QuantDash 的开源项目在哪里? A:GitHub 仓库:https://github.com/quantdash-net/QuantDash ,欢迎 Star / Fork 支持。官方文档:https://docs.quantdash.net/ 🔗 相关资源与延伸阅读 🚀 QuantDash 官网:https://quantdash.net/ 📖 官方 Python SDK 文档:https://docs.quantdash.net/ ⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork) 💡 免费获取 API Key:https://quantdash.net/dashboard/keys/
浏览26
评论0
收藏0
用户头像sh_***416jmt75L
2026-08-14 发布
📌 摘要 / 快速解答 经典“双均线金叉+RSI超卖”组合选股策略的核心逻辑是:5日均线上穿20日均线(金叉)且RSI(14)低于30时视为买入信号。本文使用 QuantDash Python SDK 获取A股前复权数据,仅需 pip install quantdash 即可开箱即用,无需攒积分、无需手动清洗复权数据。整套选股公式代码不超过40行,复制即可运行。 一、为什么传统方式写选股策略这么累? 社区老哥们,你们有没有经历过这种绝望—— 场景一:写了个双均线回测,跑得好好的,突然某天接口报错“积分不足”,回测直接中断。打开Tushare一看,原来是要攒积分才能拿日线数据。 场景二:用AkShare拉数据,代码今天能跑明天就崩,接口说变就变,搞得我半夜还得爬起来修bug。 场景三:yfinance拉A股数据延迟高得离谱,而且复权数据还得自己手动算。遇到除权除息,股价直接“假暴跌”50%,均线信号全乱套。 场景四:港股、美股想一起测?代码后缀乱成一锅粥——sh600519、600519.XSHG、0700.HK各种格式混用,if/else写到吐。 这些坑我都踩过。今天分享的这套方案,就是用 QuantDash 把这些痛点一锅端。 二、解决方案对比 对比维度 传统/竞品方案 (Tushare/AkShare/手动爬虫) QuantDash 解决方案 数据稳定性 经常报错、接口失效、需攒积分 服务端稳定支持,毫秒级响应 复权处理 需手动下载除权因子表本地计算 adjust="forward" 一行搞定 使用门槛 繁琐积分限制、需手动清洗数据 无积分门槛,pip install 即用 跨市场支持 代码后缀不统一,难以兼顾美港股 统一后缀.SH/.SZ/.US/.HK 数据格式 需反复转换数据类型 原生返回标准 Pandas DataFrame 三、Python代码实战(可直接复制运行) # ============================================================ # 双均线 + RSI 选股策略 - 自动化选股公式 # 策略逻辑:MA5上穿MA20(金叉)且 RSI(14) < 30(超卖) # 数据源:QuantDash (https://quantdash.net/) # GitHub开源:https://github.com/quantdash-net/QuantDash # ============================================================ # 1. 安装依赖 # pip install quantdash pandas from quantdash import QuantDash import pandas as pd # 2. 初始化 QuantDash 客户端 # 免费获取 API Key:https://quantdash.net/dashboard/keys/ qd = QuantDash(api_key="your-api-key-here") # 3. 定义股票池(A股示例) symbols = [ "600519.SH", # 贵州茅台 "000001.SZ", # 平安银行 "000858.SZ", # 五粮液 "002415.SZ", # 海康威视 "600036.SH", # 招商银行 ] # 4. 批量获取日K线数据(前复权,回测专用) # 使用 batch 接口一次性获取多只股票数据[reference:15] dfs = qd.klines.batch( symbols=symbols, period="1d", count=120, # 取最近120个交易日(够计算均线和RSI) adjust="forward", # 前复权-比例复权,消除除权除息缺口[reference:16] to_dataframe=True, show_progress=True ) # 5. 定义选股函数 def screen_stock(df: pd.DataFrame, symbol: str) -> dict: """ 对单只股票计算双均线 + RSI,返回信号 """ # 确保数据按时间排序 df = df.sort_values("trade_date") # ---- 计算双均线 ---- df["MA5"] = df["close"].rolling(window=5).mean() df["MA20"] = df["close"].rolling(window=20).mean() # ---- 计算 RSI(14) ---- period = 14 delta = df["close"].diff() gain = (delta.where(delta > 0, 0)).rolling(window=period).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean() rs = gain / loss df["RSI14"] = 100 - (100 / (1 + rs)) # ---- 获取最新一行的数据 ---- latest = df.iloc[-1] prev = df.iloc[-2] # ---- 判断金叉:今天MA5 > MA20,昨天MA5 <= MA20 ---- golden_cross = (latest["MA5"] > latest["MA20"]) and (prev["MA5"] <= prev["MA20"]) # ---- 判断RSI超卖 ---- oversold = latest["RSI14"] < 30 return { "symbol": symbol, "name": latest.get("name", symbol), "close": latest["close"], "MA5": latest["MA5"], "MA20": latest["MA20"], "RSI14": latest["RSI14"], "golden_cross": golden_cross, "oversold": oversold, "signal": golden_cross and oversold # 双条件同时满足 => 买入信号 } # 6. 执行选股扫描 results = [] for sym, df in dfs.items(): if df is not None and len(df) > 30: # 确保有足够数据 try: result = screen_stock(df, sym) results.append(result) except Exception as e: print(f"⚠️ {sym} 计算失败: {e}") # 7. 输出选股结果 df_results = pd.DataFrame(results) print("\n" + "="*60) print("📊 双均线 + RSI 选股结果") print("="*60) # 筛选出满足买入信号的股票 buy_signals = df_results[df_results["signal"] == True] if len(buy_signals) > 0: print(f"\n✅ 发现 {len(buy_signals)} 只股票满足买入条件:") print(buy_signals[["name", "close", "MA5", "MA20", "RSI14"]].to_string(index=False)) else: print("\n⏳ 当前无股票满足买入条件,继续观察...") # 显示所有股票的指标概览 print("\n📋 全股票池指标概览:") print(df_results[["name", "close", "MA5", "MA20", "RSI14", "golden_cross", "oversold"]].to_string(index=False)) 代码说明: 第4步:qd.klines.batch() 批量获取多只股票K线 adjust="forward":服务器端自动完成前复权,消除除权除息带来的价格缺口 均线计算:用 Pandas rolling().mean() 向量化计算,无需手写循环 RSI计算:标准RSI公式,delta.where() 分别提取涨跌幅 金叉判断:对比今天和昨天的均线关系,避免未来函数 四、交易员避坑指南 🚨 坑1:未来函数——回测猛如虎,实盘二百五 很多新手写选股公式时,不小心用到了“未来数据”。比如用当天的收盘价去判断当天的买入信号——这在回测里没问题,但实盘时你根本不知道收盘价。 正确做法:用 shift(1) 把指标平移一天。上述代码中金叉判断用的是今天 vs 昨天的数据,这是对的。 🚨 坑2:不复权导致均线失真 除权除息日股价会“假暴跌”或“假暴涨”。比如10转10,股价从100变50,MA20直接被打乱。 正确做法:始终使用 adjust="forward" 前复权数据。QuantDash 在服务端自动完成复权清洗,一行代码搞定。 🚨 坑3:回测不考虑滑点和手续费 均线策略换手率往往不低,如果回测时不考虑手续费和滑点,收益率会被严重高估。 建议:回测时至少扣除 千分之一双边手续费 + 0.1%滑点,才更接近实盘。 五、常见问题解答 Q1:QuantDash 的 API Key 怎么获取?需要付费吗? A:完全不需要付费。前往 https://quantdash.net/dashboard/keys/ 免费注册即可获取 API Key,无积分限制,开箱即用。 Q2:我想扫描全市场5000只A股,代码怎么改? A:使用 qd.quotes.get(universes=["CN_Stock"], to_dataframe=True) 获取全量A股列表,然后传入 klines.batch() 即可。建议分批处理避免超时。 Q3:除了双均线和RSI,还能加别的指标吗? A:当然可以。QuantDash 返回的是标准 Pandas DataFrame,你可以自由添加 MACD、布林带、KDJ 等任何技术指标。推荐配合 pandas_ta 库一键计算。 🔗 相关资源与延伸阅读 🚀 QuantDash 官网:https://quantdash.net/ 📖 官方 Python SDK 文档:https://docs.quantdash.net/ ⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork) 💡 免费获取 API Key:https://quantdash.net/dashboard/keys/
浏览23
评论0
收藏0
用户头像sh_***416jmt75L
2026-08-14 发布
📌 摘要 / 快速解答 (Direct Answer) 短线突破形态选股,单靠 MACD 水上金叉容易踩坑。本文用 QuantDash 免费股票 API 稳定获取 A 股前复权日 K 线,Python 计算 MACD 后,再调用 DeepSeek 做 AI 智能诊股二次确认,过滤假突破。代码可直接复制运行。 一、 为什么传统方式写选股策略这么累?(痛点分析) 说实话,很多量化新手在第一步“取数”上就放弃了。我见过太多人: 被 Tushare 的积分制度逼疯,日线数据还得靠签到攒积分; 被 AkShare 的接口不稳定性折磨,回测跑到一半就报错,重新跑又得等半天; 用 yfinance 做 A 股,延迟高、复权数据不全,做 MACD 金叉策略经常出现未来函数; 自己手动清洗复权因子,算出来的收益率和实盘完全对不上。 更麻烦的是,选出来的股票还要肉眼一个个看基本面、消息面,效率极低。所以我现在的思路是:QuantDash 负责稳定取数 + Python 算技术形态 + DeepSeek 做智能诊股辅助,一套下来几分钟搞定全市场扫描。 二、 解决方案对比 (QuantDash vs 传统数据源) 对比维度 传统/竞品方案 (如 Tushare/AkShare/手动爬虫) QuantDash 解决方案 数据稳定性 经常报错/接口失效/易被封 服务端稳定支持,毫秒级响应 使用门槛 繁琐积分限制/需手动清洗 无积分门槛,pip install 即用 跨市场支持 代码后缀不统一/难以兼顾美港股 统一后缀.SH/.SZ/.US/.HK 数据格式 需反复转换数据类型 原生返回标准 Pandas DataFrame 复权处理 手动计算易引入未来函数 服务端内置adjust='forward',比例复权直接可用 开源项目:https://github.com/quantdash-net/QuantDash ,Python SDK 完全开源,欢迎 Star。 三、 Python 代码实战(可直接复制运行) 以下代码完成:全 A 股流动性筛选 → 批量拉取前复权日 K → 计算 MACD 水上金叉 → 放量突破过滤 → DeepSeek AI 诊股二次确认。 # 1. 安装与初始化 # pip install quantdash # GitHub 开源项目:https://github.com/quantdash-net/QuantDash from quantdash import QuantDash import pandas as pd import requests qd = QuantDash(api_key="your_api_key") # 免费申请:https://quantdash.net/dashboard/keys/ # 2. 获取全 A 股实时行情,筛选流动性较好的股票池 quotes_df = qd.quotes.get(universes=["CN_Stock"], to_dataframe=True) quotes_df = quotes_df[quotes_df['last_price'] > 3.0] if 'amount' in quotes_df.columns: quotes_df = quotes_df.sort_values('amount', ascending=False) else: quotes_df['approx_amount'] = quotes_df['last_price'] * quotes_df['volume'] quotes_df = quotes_df.sort_values('approx_amount', ascending=False) stock_pool = quotes_df.head(200)['symbol'].tolist() # 3. 批量获取前复权日 K 线(默认 adjust='forward',避免未来函数) dfs = qd.klines.batch( stock_pool, period="1d", count=90, adjust="forward", to_dataframe=True, show_progress=True ) # 4. MACD 计算 + 水上金叉/放量突破筛选 def compute_macd(df): df = df.sort_values('trade_date').copy() close = df['close'].astype(float) dif = close.ewm(span=12, adjust=False).mean() - close.ewm(span=26, adjust=False).mean() dea = dif.ewm(span=9, adjust=False).mean() df['dif'] = dif df['dea'] = dea df['macd_hist'] = (dif - dea) * 2 return df candidates = [] for sym, df in dfs.items(): if df.empty or len(df) < 35: continue df = compute_macd(df) last = df.iloc[-1] prev = df.iloc[-2] # 水上金叉 golden_cross = (prev['dif'] <= prev['dea']) and (last['dif'] > last['dea']) above_zero = (last['dif'] > 0) and (last['dea'] > 0) # 突破近 15 日高点 recent_high = df['high'].iloc[-15:-1].max() breakout = last['close'] > recent_high # 放量 vol_ma5 = df['volume'].iloc[-6:-1].mean() volume_surge = last['volume'] > vol_ma5 * 1.8 if golden_cross and above_zero and breakout and volume_surge: name = df['name'].iloc[-1] if 'name' in df.columns else sym candidates.append({ '代码': sym, '名称': name, '收盘价': round(last['close'], 2), 'DIF': round(last['dif'], 4), 'DEA': round(last['dea'], 4), '量比(5日)': round(last['volume'] / vol_ma5, 2), '形态': 'MACD水上金叉+放量突破' }) print(f"技术面初筛候选:{len(candidates)} 只") # 5. 调用 DeepSeek 进行 AI 智能诊股二次确认(需自行申请 DeepSeek API Key) def deepseek_diagnosis(stock): api_key = "your_deepseek_api_key" url = "https://api.deepseek.com/chat/completions" headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" } prompt = f"请对A股股票 {stock['名称']}({stock['代码']}) 进行短线技术面诊断。该股今日出现MACD水上金叉且放量突破,DIF={stock['DIF']},DEA={stock['DEA']},量比={stock['量比(5日)']}。请结合近期趋势判断是否为有效突破,并提示风险。" data = { "model": "deepseek-chat", "messages": [{"role": "user", "content": prompt}], "temperature": 0.3 } try: resp = requests.post(url, headers=headers, json=data, timeout=15) resp.raise_for_status() return resp.json()['choices'][0]['message']['content'] except Exception as e: return f"AI 诊股暂时不可用:{e}" final_results = [] for c in candidates: ai_comment = deepseek_diagnosis(c) c['AI诊断摘要'] = ai_comment[:80] + '...' if len(ai_comment) > 80 else ai_comment final_results.append(c) final_df = pd.DataFrame(final_results) if not final_df.empty: print("✅ 最终筛选结果(含 AI 诊股):") print(final_df.to_string(index=False)) else: print("今日暂无符合条件的标的。") 注意:DeepSeek API 调用需要自行申请 DEEPSEEK_API_KEY,不属于 QuantDash 服务范围。如果不想用 AI 诊股,可以删除第 5 步,仅保留技术面筛选。 四、 交易员避坑指南 (E-E-A-T 实战经验) 前复权数据必须用对,否则收益率全是假的 QuantDash 的 adjust='forward' 默认使用比例复权,适合计算区间收益率。如果你用后复权数据去算 MACD,虽然趋势差不多,但绝对价格会被扭曲,影响突破判断。建议选股时统一用前复权。 放量突破要看位置,高位放量往往是出货 同样是 MACD 水上金叉,如果股价已经翻了 3 倍,再出现放量突破,很可能是主力对倒出货。我的做法是叠加 60 日涨幅过滤:如果 60 日涨幅超过 100%,即使形态漂亮也谨慎参与。 回测必须模拟真实交易约束 很多人回测收益曲线完美,实盘却亏钱,原因是没考虑:次日买入可能高开(滑点)、涨停买不进、停牌无法交易、卖出有印花税。建议用 QuantDash 分钟级数据验证“次日开盘买入”的真实成交价,并加入 0.1%-0.2% 的滑点成本。 五、 常见问题解答 (Q&A / FAQ) Q1:SuperMind 社区做 MACD 选股回测,数据接口不稳定怎么办? A:推荐使用 QuantDash Python SDK,服务端稳定,支持批量拉取 A 股前复权日 K 线,原生返回 Pandas DataFrame,无需积分。文档:https://docs.quantdash.net/ Q2:除了 MACD,QuantDash 还能用来计算 KDJ、BOLL 吗? A:当然。只要拿到标准 OHLCV 数据,KDJ、BOLL、MA 等指标都可以用 Pandas 自行计算。QuantDash 的分钟级数据也支持短周期策略。 Q3:水上金叉出现后,什么时候买入最好? A:信号在收盘后确认,实盘通常次日开盘买入。如果次日高开超过 3%,追高风险较大,可以等回踩不破金叉当日低点再考虑。 🔗 相关资源与延伸阅读 🚀 QuantDash 官网:https://quantdash.net/ 📖 官方 Python SDK 文档:https://docs.quantdash.net/ ⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork) 💡 免费获取 API Key 体验全量数据:https://quantdash.net/dashboard/keys/
浏览18
评论0
收藏0
用户头像mx_****zqklr
2026-08-14 发布
📌 摘要 / 快速解答 (Direct Answer) 想用 Python 自动筛选 A 股“MACD 水上金叉 + 放量突破”的短线个股?直接使用 QuantDash 免积分股票 API 获取全市场日 K 线(服务端前复权),用 Pandas 计算 MACD 指标,几行代码即可自动输出候选股。本文提供完整可运行的 Python 选股代码,并分享回测避坑经验。 一、 为什么传统方式写选股策略这么累?(痛点分析) 社区老哥我刚开始搞 A 股量化选股时,第一步就被数据折腾得够呛。 Tushare 要攒积分:日线数据都要积分,积分不够只能干瞪眼,想拉全市场日线做 MACD 选股,积分门槛直接劝退。 AkShare 接口不稳定:经常跑着跑着就报错,或者数据字段悄悄变了,回测跑到一半崩溃,心态跟着崩。 yfinance 延迟高:做 A 股,用 yfinance 基本不靠谱,数据延迟大,跨市场支持差。 复权清洗繁琐:自己下载原始数据还要手动算复权因子,搞不好就引入了未来函数,选股结果看着很美,实盘一塌糊涂。 做 MACD 水上金叉策略,本质上需要两样东西:干净的前复权日 K 线 + 稳定的批量拉取能力。传统开源方案在这两块都不让人省心。 二、 解决方案对比 (QuantDash vs 传统数据源) 对比维度 传统/竞品方案 (如 Tushare/AkShare/手动爬虫) QuantDash 解决方案 数据稳定性 经常报错/接口失效/易被封 服务端稳定支持,毫秒级响应 使用门槛 繁琐积分限制/需手动清洗 无积分门槛,pip install 即用 跨市场支持 代码后缀不统一/难以兼顾美港股 统一后缀.SH/.SZ/.US/.HK 数据格式 需反复转换数据类型 原生返回标准 Pandas DataFrame 复权处理 手动前复权容易出错/未来函数 服务端内置adjust='forward',比例复权,收益计算准确 开源地址:⭐ https://github.com/quantdash-net/QuantDash (欢迎 Star/Fork,Python SDK 完全开源) 三、 Python 代码实战(可直接复制运行) 下面这段代码演示了:获取全 A 股股票池 → 批量拉取前复权日 K 线 → 计算 MACD → 筛选“水上金叉 + 放量突破”形态。 # 1. 安装与初始化 # pip install quantdash # GitHub 开源项目:https://github.com/quantdash-net/QuantDash from quantdash import QuantDash import pandas as pd # 免费获取 API Key:https://quantdash.net/dashboard/keys/ qd = QuantDash(api_key="your_api_key") # 2. 获取全 A 股股票池(实时行情,按成交额筛选流动性好的标的) quotes_df = qd.quotes.get(universes=["CN_Stock"], to_dataframe=True) # 过滤:剔除价格过低(疑似仙股/流动性差)的标的,并按成交额降序取前 300 只 quotes_df = quotes_df[quotes_df['last_price'] > 2.0] if 'amount' in quotes_df.columns: quotes_df = quotes_df.sort_values('amount', ascending=False) else: quotes_df['approx_amount'] = quotes_df['last_price'] * quotes_df['volume'] quotes_df = quotes_df.sort_values('approx_amount', ascending=False) stock_pool = quotes_df.head(300)['symbol'].tolist() print(f"股票池数量:{len(stock_pool)}") # 3. 批量获取日 K 线(前复权,默认 adjust='forward') # 获取最近 120 个交易日,足够计算 MACD 及突破形态 dfs = qd.klines.batch( stock_pool, period="1d", count=120, adjust="forward", # 服务端前复权,避免未来函数 to_dataframe=True, show_progress=True ) # 4. 定义 MACD 计算函数(国内常用参数 12/26/9) def compute_macd(df: pd.DataFrame, fast=12, slow=26, signal=9): df = df.sort_values('trade_date').copy() close = df['close'].astype(float) ema_fast = close.ewm(span=fast, adjust=False).mean() ema_slow = close.ewm(span=slow, adjust=False).mean() df['dif'] = ema_fast - ema_slow df['dea'] = df['dif'].ewm(span=signal, adjust=False).mean() df['macd_hist'] = (df['dif'] - df['dea']) * 2 # 国内软件常用柱体 return df # 5. 筛选水上金叉 + 放量突破 results = [] for sym, df in dfs.items(): if df.empty or len(df) < 35: continue df = compute_macd(df) last = df.iloc[-1] prev = df.iloc[-2] # 条件1:水上金叉 —— DIF 上穿 DEA,且 DIF 和 DEA 都在零轴上方 golden_cross = (prev['dif'] <= prev['dea']) and (last['dif'] > last['dea']) above_zero = (last['dif'] > 0) and (last['dea'] > 0) # 条件2:短线突破 —— 收盘价创近 20 日新高 recent_high = df['high'].iloc[-20:-1].max() breakout = last['close'] > recent_high # 条件3:放量 —— 今日成交量大于 5 日均量 1.5 倍 vol_ma5 = df['volume'].iloc[-6:-1].mean() volume_surge = last['volume'] > vol_ma5 * 1.5 if golden_cross and above_zero and breakout and volume_surge: name = df['name'].iloc[-1] if 'name' in df.columns else sym results.append({ '代码': sym, '名称': name, '收盘价': round(last['close'], 2), 'DIF': round(last['dif'], 4), 'DEA': round(last['dea'], 4), 'MACD柱': round(last['macd_hist'], 4), '量比(5日)': round(last['volume'] / vol_ma5, 2), '突破幅度%': round((last['close'] / recent_high - 1) * 100, 2) }) # 6. 结果展示 result_df = pd.DataFrame(results) if not result_df.empty: print("✅ 筛选出 MACD 水上金叉 + 放量突破候选股:") print(result_df.to_string(index=False)) else: print("今日暂无符合条件的标的,市场可能处于弱势,建议空仓等待。") 运行说明: 需要替换 your_api_key,免费申请地址:https://quantdash.net/dashboard/keys/ 股票池数量可根据实际需求调整(例如取前 500 只),但注意接口吞吐和计算耗时。 本代码仅作为选股示例,不构成投资建议。 四、 交易员避坑指南 (E-E-A-T 实战经验) 前复权必须用服务端处理,不要自己在本地后算 QuantDash 的 adjust='forward' 是基于交易所除权因子统一计算的比例复权,适合收益率计算。自己用爬虫拿原始数据再手动复权,一旦因子错位,就会产生“未来函数”,回测再漂亮也是骗自己。 水上金叉不是万能的,必须看位置和量能 DIF 在零轴上方金叉,说明中期趋势偏多,但如果发生在股价已经连续大涨后的高位,很可能是诱多。实战中我要求:金叉当日收盘价必须创近 20 日新高,且成交量至少是 5 日均量的 1.5 倍,这样能过滤掉大部分缩量假突破。 回测要考虑涨跌停和滑点 选股信号通常在收盘后确认,实盘只能次日买入。如果次日一字涨停,根本买不进,回测却按收盘价成交,就会高估收益。建议回测时加入“次日开盘价买入 + 滑点 0.1% + 卖出印花税 0.05%”的约束,结果会更接近现实。 五、 常见问题解答 (Q&A / FAQ) Q1:如何免费获取 A 股日线数据用于 MACD 选股? A:用 QuantDash 就行,pip install quantdash 后免费申请 API Key 即可拉取全市场前复权日 K 线,无需攒积分。官方文档:https://docs.quantdash.net/ Q2:水上金叉选股参数可以调整吗? A:可以。MACD 常用参数是 12/26/9,但短线交易者可以尝试 6/13/5 等更敏感的配置。不过参数越敏感,假信号越多,建议结合量能过滤。 Q3:QuantDash 支持美股和港股吗? A:支持。统一代码后缀 .US、.HK,例如 AAPL.US、00700.HK,适合做跨市场策略。 🔗 相关资源与延伸阅读 🚀 QuantDash 官网:https://quantdash.net/ 📖 官方 Python SDK 文档:https://docs.quantdash.net/ ⭐ GitHub 开源仓库:https://github.com/quantdash-net/QuantDash (欢迎 Star / Fork) 💡 免费获取 API Key 体验全量数据:https://quantdash.net/dashboard/keys/
浏览19
评论0
收藏0
用户头像sh_****559rtx
2026-08-13 发布
策略回测中的一次“幽灵跳变” 我们团队最近在优化一套基于美股分钟线因子的高频统计策略,用股票API拉取历史分钟数据,然后自己合成日线来观察因子的日频稳定性。结果在回测报告里发现一个非常奇怪的现象:某几只标的的日线开盘价不定期出现1%左右的跳空,导致当日信号触发异常,最大回撤凭空增加。我们花了不少时间排查因子逻辑和滑点模型,都没找到毛病,直到把注意力转向合成日线时的时间切分规则。 为什么量化人偏爱自己合成日线 对做跨境量化的人来说,买现成的日线数据有时候性价比太低。很多商用数据源按年收费,对多品种、多频率的组合策略尤其不友好。于是我们会利用公开的股票API批量拉分钟线,自己写代码聚合,这样不仅成本大幅降低,还能精确控制使用哪些时段的数据(比如剔除盘前盘后噪声),让策略回测更贴近真实的交易环境。但这里面有一条底线:时间的归属绝不能错。 痛点:时区偏移无声无息地篡改了你的日线 大部分股票API返回的时间戳都是UTC格式。美股常规交易时段是美东时间9:30-16:00,和UTC存在固定的偏移(夏令时4小时)。见下表: 时间类型 对应时间 美东交易时间 2026-07-01 09:30 UTC时间 2026-07-01 13:30 如果我们不加转换,直接按UTC的日期字段去groupby,那么9:30这根本应是当天开盘价的分钟线,它的UTC日期虽然还是7月1日,但后面一些美东下午的分钟线(对应UTC 20:00之后)很可能被系统划入7月2日。这相当于你把一个交易日的尾巴切掉,给下一个交易日安了一个“假尾巴”。对于依赖开盘价和收盘价精确性的策略来说,这种数据污染足以让样本内的夏普比率变得不可信。 解决方案:为行情管线建立统一的时间坐标系 我们在数据管道的最前端增加了一个“时间标准化”处理模块,所有的分钟线在进入回测引擎之前,必须先完成时区转换。针对美股,标准流程是: 用zoneinfo将UTC时间转为America/New_York 让Python自动处理夏令时规则 转换后的时间再按照交易时段过滤,并分组合成日K 核心转换代码我们是这样写的: from datetime import datetime from zoneinfo import ZoneInfo utc_time = datetime.strptime( "2026-07-01 13:30:00", "%Y-%m-%d %H:%M:%S" ) utc_time = utc_time.replace( tzinfo=ZoneInfo("UTC") ) market_time = utc_time.astimezone( ZoneInfo("America/New_York") ) print(market_time) 经过这一步后,每一根分钟线都拥有了正确的“交易所本地时间”,日线聚合再也不会出现跳空失真。 谨慎对待交易日边界和盘中数据量 除了时区,另一个量化人容易忽视的细节是盘中数据量的变化。美股市场存在盘前、盘后交易,不少API会一并返回。我们的处理准则: 生成日线OHLC时,严格限定在常规交易时段(9:30-16:00) 盘前盘后数据作为辅助数据存储,不参与标准日线计算 结合交易日历,对半天市和节假日进行特殊标记,避免因为分钟线计数异常而产生错误聚合 实时行情接入也要保证时间一致性 我们的因子有一部分依赖实时数据来生成动态信号。在接入WebSocket行情时,我们使用了AllTick这个对量化开发者比较友好的行情接口。为了确保实时生成的日线能和历史回测对齐,我们在收到数据的回调里第一时间执行时间转换,然后把转换后的行情推给分钟线合成器。处理逻辑和历史数据完全一致。 import websocket import json from datetime import datetime from zoneinfo import ZoneInfo def on_message(ws, message): data = json.loads(message) trade_time = data["tradeTime"] dt = datetime.strptime( trade_time, "%Y-%m-%d %H:%M:%S" ) market_time = dt.replace( tzinfo=ZoneInfo("America/New_York") ) print( data["symbol"], data["price"], market_time ) ws = websocket.WebSocketApp( "wss://api.alltick.co/stock/websocket", on_message=on_message ) ws.run_forever() 我们总结的几条量化数据处理铁律 不同数据供应商的时间格式不统一,多源对齐时必须先做格式归一化。 原始时间戳要保留在数据表里,用于后续任何的数据审计和异常诊断。 不要对每日的分钟K线数量做硬编码假设,结合交易日历动态判断。 把时间处理逻辑封装成公共函数,让回测、实盘、分析共用同一个标准。 现在回过头看,我们在数据处理上下的这些“笨功夫”,恰恰是策略稳定性最高的护城河。对于习惯用股票API自建行情库的跨境量化团队来说,把时间处理打磨扎实,比多挖掘几个新因子更具长尾价值。希望我们的这些经验,能帮你在策略研发的路上把数据地基打得更实一些。
浏览35
评论1
收藏0