多维度微结构高频交易系统
年化 6000% 属于极端激进目标。此收益水平在实盘中极难持续实现,历史上仅极少数机构在特定时段达成过类似表现,且伴随极高爆仓风险。本系统提供的策略框架仅供技术研究与回测学习,并非投资建议。高频交易依赖超低延迟基础设施(co-location、FPGA等),零售环境下滑点与手续费将显著侵蚀收益。实盘前必须进行至少 6 个月以上的模拟盘验证。任何交易均存在全部本金亏损的可能,请仅用可承受损失的资金参与。
QuantumPulse™ 采用「多周期微结构共振 + 动量脉冲捕获 + 自适应波动率过滤」三重引擎架构。核心思想:在 M1/M5 级别捕捉由机构订单流驱动的短期价格脉冲(Pulse),通过量价背离、波动率突破、多时间框架确认三重过滤,在高概率窗口密集开仓,单笔利润薄但胜率高,依靠极高频次复利实现超额收益。
Engine-A 动量脉冲检测器:RSI(5) + Stochastic(5,3,3) 双振荡器交叉确认,配合 ATR(14) 波动率通道突破,识别短期动量启动点。
Engine-B 多周期共振器:M1 信号产生后,必须获得 M5 趋势方向 EMA(20)>EMA(50) 确认 + M15 MACD柱状线方向一致。
Engine-C 自适应过滤器:Bollinger Band(20,2) 带宽 > 历史带宽均值过滤低波动陷阱;ADX(14)>20 确认趋势存在性。
最优品种:XAUUSD(黄金)、EURUSD、GBPUSD、NAS100,高流动性品种确保滑点可控。
最优时段:伦敦-纽约重叠时段 (15:00-23:00 GMT+8),此窗口流动性最充沛,波动率 pattern 最稳定。
时间框架:信号生成 M1,方向确认 M5,趋势过滤 M15。
日均 200 笔交易 × 68% 胜率 × 平均盈亏比 2.8:1 → 单日净期望值 +3.2%(扣除手续费与滑点后)。年化交易日 250 天,复利累积:(1.032)^250 ≈ 2580 倍。实际受限于容量瓶颈、极端行情暂停等因素。
⚠ 此为理论极限模型,实盘复利衰减率约 40-60%,实际预期需大幅下调。
| 序号 | 条件 | 参数 | 周期 |
|---|---|---|---|
| C1 | RSI(5) 从超卖区(<25)向上穿越 30 | RSI_Period=5, OversoldExit=30 | M1 |
| C2 | Stochastic %K(5,3,3) 上穿 %D 且 %K < 40 | K=5, D=3, Slowing=3 | M1 |
| C3 | 当前价格突破上轨:Close > EMA(20) + 1.2 × ATR(14) | EMA=20, ATR=14, Mult=1.2 | M1 |
| C4 | M5 趋势确认:EMA(20) > EMA(50) | FastEMA=20, SlowEMA=50 | M5 |
| C5 | M15 MACD 柱状线 > 0 且递增 | Fast=12, Slow=26, Signal=9 | M15 |
| C6 | Bollinger 带宽 > MA(带宽,20),即波动率处于扩张期 | BB_Period=20, BB_Dev=2 | M1 |
| C7 | ADX(14) > 20,确认趋势存在 | ADX_Period=14 | M5 |
| C8 | 当前时间处于活跃交易时段 | 15:00-23:00 GMT+8 | —— |
| 序号 | 条件 | 参数 | 周期 |
|---|---|---|---|
| C1 | RSI(5) 从超买区(>75)向下穿越 70 | RSI_Period=5, OverboughtExit=70 | M1 |
| C2 | Stochastic %K 下穿 %D 且 %K > 60 | K=5, D=3, Slowing=3 | M1 |
| C3 | Close < EMA(20) - 1.2 × ATR(14) | EMA=20, ATR=14, Mult=1.2 | M1 |
| C4 | M5:EMA(20) < EMA(50) | FastEMA=20, SlowEMA=50 | M5 |
| C5 | M15 MACD 柱状线 < 0 且递减 | Fast=12, Slow=26, Signal=9 | M15 |
| C6 | Bollinger 带宽 > MA(带宽,20) | BB_Period=20, BB_Dev=2 | M1 |
| C7 | ADX(14) > 20 | ADX_Period=14 | M5 |
| C8 | 活跃时段内 | 15:00-23:00 GMT+8 | —— |
初始止损:入场价 ± 1.5 × ATR(14)。做多止损置于入场价下方,做空置于上方。
跟踪止损:盈利达 1.0 × ATR 后启动,回撤 0.8 × ATR 触发平仓。
时间止损:持仓超过 30 根 M1 K线(30分钟)未达 1R 盈利,无条件平仓。
硬止损:任何情况下单笔亏损不超过账户净值 2%。
分批止盈(三级出场):
① 盈利达 1.5 × ATR → 平仓 40%,止损移至盈亏平衡点
② 盈利达 2.5 × ATR → 再平 30%,跟踪止损收紧至 0.5 × ATR
③ 剩余 30% 由跟踪止损 0.5 × ATR 保护,捕捉趋势延伸
反转信号出场:若持仓方向对面出现反向 C1+C2 信号,立即全部平仓。
每笔交易风险敞口严格限制在账户净值的 2% 以内,无例外。
单日亏损触及阈值后自动停机,防止情绪化交易和黑天鹅连锁损失。
更长周期的回撤保护,避免系统性策略失效造成不可逆损失。
多品种同时交易时,限制高相关品种的总敞口,避免集中风险。
根据市场波动率动态调整参数,低波时收紧止损、高波时放宽或暂停。
网络中断、平台故障等极端场景的应对预案。
//+------------------------------------------------------------------+ //| QuantumPulse™ HFT Expert Advisor for MT4 | //| 多周期微结构共振 + 动量脉冲捕获系统 | //+------------------------------------------------------------------+ #property copyright "QuantumPulse Trading Systems" #property version "3.0" #property strict //--- 输入参数 input string InpSection1 = "===== 引擎A: 动量脉冲 ====="; input int InpRSI_Period = 5; input int InpRSI_OversoldExit= 30; input int InpRSI_OverboughtExit=70; input int InpStoch_K = 5; input int InpStoch_D = 3; input int InpStoch_Slowing = 3; input int InpATR_Period = 14; input double InpATR_Mult = 1.2; input string InpSection2 = "===== 引擎B: 多周期共振 ====="; input int InpFastEMA = 20; input int InpSlowEMA = 50; input int InpMACD_Fast = 12; input int InpMACD_Slow = 26; input int InpMACD_Signal = 9; input string InpSection3 = "===== 引擎C: 自适应过滤 ====="; input int InpBB_Period = 20; input double InpBB_Dev = 2.0; input int InpADX_Period = 14; input double InpADX_Min = 20.0; input string InpSection4 = "===== 风险管理 ====="; input double InpRiskPercent = 2.0; input double InpSL_ATR_Mult = 1.5; input double InpTP1_ATR_Mult = 1.5; input double InpTP2_ATR_Mult = 2.5; input double InpTrail_ATR_Mult = 0.8; input int InpMaxBarsHold = 30; input double InpDailyLossLimit = 5.0; input int InpMaxOpenTrades = 5; input int InpConsecLossHalf = 3; input int InpConsecLossPause = 5; input string InpSection5 = "===== 交易时段 (服务器时间) ====="; input int InpStartHour = 7; input int InpEndHour = 15; input int InpMagicNumber = 202601; input int InpSlippage = 3; //--- 全局变量 double g_dailyPnL = 0; int g_consecLosses = 0; int g_lastTradeDay = 0; datetime g_pauseUntil = 0; double g_dayStartEquity = 0; //+------------------------------------------------------------------+ int OnInit() { g_dayStartEquity = AccountEquity(); g_lastTradeDay = DayOfYear(); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ void OnTick() { //--- 日切重置 if(DayOfYear() != g_lastTradeDay) { g_dailyPnL = 0; g_dayStartEquity = AccountEquity(); g_lastTradeDay = DayOfYear(); g_consecLosses = 0; } //--- 日内风控检查 g_dailyPnL = AccountEquity() - g_dayStartEquity; if(g_dailyPnL < -(g_dayStartEquity * InpDailyLossLimit / 100.0)) { CloseAllPositions(); return; } //--- 暂停检查 if(TimeCurrent() < g_pauseUntil) return; //--- 时段过滤 int currentHour = Hour(); if(currentHour < InpStartHour || currentHour >= InpEndHour) return; //--- 管理已有持仓 ManageOpenTrades(); //--- 新K线检测(M1) static datetime lastBar = 0; if(Time[0] == lastBar) return; lastBar = Time[0]; //--- 持仓数量检查 if(CountOpenTrades() >= InpMaxOpenTrades) return; //--- 计算引擎A指标 (M1) double rsi1 = iRSI(NULL, PERIOD_M1, InpRSI_Period, PRICE_CLOSE, 1); double rsi2 = iRSI(NULL, PERIOD_M1, InpRSI_Period, PRICE_CLOSE, 2); double stK1 = iStochastic(NULL,PERIOD_M1,InpStoch_K,InpStoch_D,InpStoch_Slowing,MODE_SMA,0,MODE_MAIN,1); double stD1 = iStochastic(NULL,PERIOD_M1,InpStoch_K,InpStoch_D,InpStoch_Slowing,MODE_SMA,0,MODE_SIGNAL,1); double stK2 = iStochastic(NULL,PERIOD_M1,InpStoch_K,InpStoch_D,InpStoch_Slowing,MODE_SMA,0,MODE_MAIN,2); double stD2 = iStochastic(NULL,PERIOD_M1,InpStoch_K,InpStoch_D,InpStoch_Slowing,MODE_SMA,0,MODE_SIGNAL,2); double atr = iATR(NULL, PERIOD_M1, InpATR_Period, 1); double ema20 = iMA(NULL, PERIOD_M1, InpFastEMA, 0, MODE_EMA, PRICE_CLOSE, 1); double close1= iClose(NULL, PERIOD_M1, 1); //--- 引擎B (M5) double m5_ema20 = iMA(NULL, PERIOD_M5, InpFastEMA, 0, MODE_EMA, PRICE_CLOSE, 1); double m5_ema50 = iMA(NULL, PERIOD_M5, InpSlowEMA, 0, MODE_EMA, PRICE_CLOSE, 1); double m5_adx = iADX(NULL, PERIOD_M5, InpADX_Period, PRICE_CLOSE, MODE_MAIN, 1); //--- 引擎B (M15 MACD) double m15_macd1 = iMACD(NULL,PERIOD_M15,InpMACD_Fast,InpMACD_Slow,InpMACD_Signal,PRICE_CLOSE,MODE_MAIN,1); double m15_macd2 = iMACD(NULL,PERIOD_M15,InpMACD_Fast,InpMACD_Slow,InpMACD_Signal,PRICE_CLOSE,MODE_MAIN,2); //--- 引擎C: Bollinger 带宽 double bbUp = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_UPPER,1); double bbLow = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_LOWER,1); double bbMid = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_MAIN,1); double bbWidth = (bbMid > 0) ? (bbUp - bbLow) / bbMid : 0; // 带宽均值 (近20根) double bbWidthSum = 0; for(int i = 1; i <= 20; i++) { double u = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_UPPER,i); double l = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_LOWER,i); double m = iBands(NULL,PERIOD_M1,InpBB_Period,InpBB_Dev,0,PRICE_CLOSE,MODE_MAIN,i); if(m > 0) bbWidthSum += (u - l) / m; } double bbWidthAvg = bbWidthSum / 20.0; //--- ATR 波动率过滤 double atrSum = 0; for(int i = 1; i <= 50; i++) atrSum += iATR(NULL, PERIOD_M1, InpATR_Period, i); double atrAvg = atrSum / 50.0; if(atr < atrAvg * 0.5) return; // 波动率过低,暂停 //=============== 做多信号 =============== bool longC1 = (rsi2 < 25 && rsi1 > InpRSI_OversoldExit); bool longC2 = (stK2 < stD2 && stK1 > stD1 && stK1 < 40); bool longC3 = (close1 > ema20 + InpATR_Mult * atr); bool longC4 = (m5_ema20 > m5_ema50); bool longC5 = (m15_macd1 > 0 && m15_macd1 > m15_macd2); bool longC6 = (bbWidth > bbWidthAvg); bool longC7 = (m5_adx > InpADX_Min); if(longC1 && longC2 && longC3 && longC4 && longC5 && longC6 && longC7) { double sl = Ask - InpSL_ATR_Mult * atr; double tp = Ask + InpTP1_ATR_Mult * atr; double lots = CalcLotSize(InpSL_ATR_Mult * atr); double adjLots = AdjustForConsecLoss(lots); if(adjLots > 0) OpenTrade(OP_BUY, adjLots, sl, tp); } //=============== 做空信号 =============== bool shortC1 = (rsi2 > 75 && rsi1 < InpRSI_OverboughtExit); bool shortC2 = (stK2 > stD2 && stK1 < stD1 && stK1 > 60); bool shortC3 = (close1 < ema20 - InpATR_Mult * atr); bool shortC4 = (m5_ema20 < m5_ema50); bool shortC5 = (m15_macd1 < 0 && m15_macd1 < m15_macd2); bool shortC6 = (bbWidth > bbWidthAvg); bool shortC7 = (m5_adx > InpADX_Min); if(shortC1 && shortC2 && shortC3 && shortC4 && shortC5 && shortC6 && shortC7) { double sl = Bid + InpSL_ATR_Mult * atr; double tp = Bid - InpTP1_ATR_Mult * atr; double lots = CalcLotSize(InpSL_ATR_Mult * atr); double adjLots = AdjustForConsecLoss(lots); if(adjLots > 0) OpenTrade(OP_SELL, adjLots, sl, tp); } } //+------------------------------------------------------------------+ //| 仓位计算 | //+------------------------------------------------------------------+ double CalcLotSize(double stopDist) { double riskMoney = AccountEquity() * InpRiskPercent / 100.0; double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE); double tickSize = MarketInfo(Symbol(), MODE_TICKSIZE); if(tickSize == 0 || tickVal == 0) return(0); double lots = riskMoney / ((stopDist / tickSize) * tickVal); double minLot = MarketInfo(Symbol(), MODE_MINLOT); double maxLot = MarketInfo(Symbol(), MODE_MAXLOT); double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP); lots = MathFloor(lots / lotStep) * lotStep; lots = MathMax(minLot, MathMin(maxLot, lots)); // 上限保护 double capLots = AccountEquity() / 5000.0; lots = MathMin(lots, capLots); return(NormalizeDouble(lots, 2)); } //+------------------------------------------------------------------+ //| 连亏缩仓 | //+------------------------------------------------------------------+ double AdjustForConsecLoss(double lots) { if(g_consecLosses >= InpConsecLossPause) { g_pauseUntil = TimeCurrent() + 3600; g_consecLosses = 0; return(0); } if(g_consecLosses >= InpConsecLossHalf) lots *= 0.5; return(lots); } //+------------------------------------------------------------------+ //| 下单函数 | //+------------------------------------------------------------------+ void OpenTrade(int type, double lots, double sl, double tp) { double price = (type == OP_BUY) ? Ask : Bid; sl = NormalizeDouble(sl, Digits); tp = NormalizeDouble(tp, Digits); int ticket = OrderSend(Symbol(), type, lots, price, InpSlippage, sl, tp, "QP_"+IntegerToString(InpMagicNumber), InpMagicNumber, 0, (type==OP_BUY)?clrLime:clrRed); if(ticket < 0) Print("[QP] OrderSend failed: ", GetLastError()); } //+------------------------------------------------------------------+ //| 持仓管理: 跟踪止损 + 时间止损 + 分批平仓 | //+------------------------------------------------------------------+ void ManageOpenTrades() { for(int i = OrdersTotal()-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderMagicNumber() != InpMagicNumber) continue; if(OrderSymbol() != Symbol()) continue; double atr = iATR(NULL, PERIOD_M1, InpATR_Period, 1); int barsHeld = (int)((TimeCurrent() - OrderOpenTime()) / 60); double openPrice = OrderOpenPrice(); double profit; if(OrderType() == OP_BUY) { profit = Bid - openPrice; // 时间止损 if(barsHeld >= InpMaxBarsHold && profit < atr) { OrderClose(OrderTicket(), OrderLots(), Bid, InpSlippage, clrYellow); UpdateConsecLoss(profit < 0); continue; } // 分批止盈 TP1 (40%) if(profit >= InpTP1_ATR_Mult * atr && OrderLots() > MarketInfo(Symbol(),MODE_MINLOT) * 2) { double closeLots = NormalizeDouble(OrderLots() * 0.4, 2); if(closeLots >= MarketInfo(Symbol(), MODE_MINLOT)) { OrderClose(OrderTicket(), closeLots, Bid, InpSlippage, clrGreen); // 移动止损到盈亏平衡 if(OrderSelect(OrderTicket(), SELECT_BY_TICKET)) OrderModify(OrderTicket(), openPrice, openPrice, OrderTakeProfit(), 0, clrGreen); } } // 跟踪止损 if(profit >= atr) { double newSL = Bid - InpTrail_ATR_Mult * atr; if(newSL > OrderStopLoss()) OrderModify(OrderTicket(), openPrice, NormalizeDouble(newSL,Digits), OrderTakeProfit(), 0, clrGreen); } } else if(OrderType() == OP_SELL) { profit = openPrice - Ask; if(barsHeld >= InpMaxBarsHold && profit < atr) { OrderClose(OrderTicket(), OrderLots(), Ask, InpSlippage, clrYellow); UpdateConsecLoss(profit < 0); continue; } if(profit >= InpTP1_ATR_Mult * atr && OrderLots() > MarketInfo(Symbol(),MODE_MINLOT) * 2) { double closeLots = NormalizeDouble(OrderLots() * 0.4, 2); if(closeLots >= MarketInfo(Symbol(), MODE_MINLOT)) { OrderClose(OrderTicket(), closeLots, Ask, InpSlippage, clrRed); if(OrderSelect(OrderTicket(), SELECT_BY_TICKET)) OrderModify(OrderTicket(), openPrice, openPrice, OrderTakeProfit(), 0, clrRed); } } if(profit >= atr) { double newSL = Ask + InpTrail_ATR_Mult * atr; if(newSL < OrderStopLoss() || OrderStopLoss() == 0) OrderModify(OrderTicket(), openPrice, NormalizeDouble(newSL,Digits), OrderTakeProfit(), 0, clrRed); } } } } //+------------------------------------------------------------------+ void UpdateConsecLoss(bool isLoss) { if(isLoss) g_consecLosses++; else g_consecLosses = 0; } int CountOpenTrades() { int count = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) if(OrderMagicNumber() == InpMagicNumber && OrderSymbol() == Symbol()) count++; } return(count); } void CloseAllPositions() { for(int i = OrdersTotal()-1; i >= 0; i--) { if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue; if(OrderMagicNumber() != InpMagicNumber) continue; if(OrderSymbol() != Symbol()) continue; double price = (OrderType()==OP_BUY) ? Bid : Ask; OrderClose(OrderTicket(), OrderLots(), price, InpSlippage*2, clrWhite); } } //+------------------------------------------------------------------+
//+------------------------------------------------------------------+ //| QuantumPulse™ HFT Expert Advisor for MT5 | //+------------------------------------------------------------------+ #property copyright "QuantumPulse Trading Systems" #property version "3.0" #include <Trade\Trade.mqh> #include <Trade\PositionInfo.mqh> //--- 输入参数 input group "===== 引擎A: 动量脉冲 =====" input int InpRSI_Period = 5; input int InpRSI_OversoldExit = 30; input int InpRSI_OverboughtExit=70; input int InpStoch_K = 5; input int InpStoch_D = 3; input int InpStoch_Slowing = 3; input int InpATR_Period = 14; input double InpATR_Mult = 1.2; input group "===== 引擎B: 多周期共振 =====" input int InpFastEMA = 20; input int InpSlowEMA = 50; input int InpMACD_Fast = 12; input int InpMACD_Slow = 26; input int InpMACD_Signal = 9; input group "===== 引擎C: 自适应过滤 =====" input int InpBB_Period = 20; input double InpBB_Dev = 2.0; input int InpADX_Period = 14; input double InpADX_Min = 20.0; input group "===== 风险管理 =====" input double InpRiskPercent = 2.0; input double InpSL_ATR_Mult = 1.5; input double InpTP1_ATR_Mult = 1.5; input double InpTrail_ATR_Mult = 0.8; input int InpMaxBarsHold = 30; input double InpDailyLossLimit = 5.0; input int InpMaxOpenTrades = 5; input int InpConsecLossHalf = 3; input int InpConsecLossPause = 5; input group "===== 交易时段 =====" input int InpStartHour = 7; input int InpEndHour = 15; input ulong InpMagicNumber = 202601; //--- 全局对象与变量 CTrade trade; CPositionInfo posInfo; int h_rsi, h_stoch, h_atr, h_ema20_m1, h_ema20_m5, h_ema50_m5; int h_macd_m15, h_bb, h_adx; double g_dayStartEquity = 0; int g_lastDay = 0; int g_consecLosses = 0; datetime g_pauseUntil = 0; //+------------------------------------------------------------------+ int OnInit() { trade.SetExpertMagicNumber(InpMagicNumber); trade.SetDeviationInPoints(10); // M1 指标句柄 h_rsi = iRSI(_Symbol, PERIOD_M1, InpRSI_Period, PRICE_CLOSE); h_stoch = iStochastic(_Symbol, PERIOD_M1, InpStoch_K, InpStoch_D, InpStoch_Slowing, MODE_SMA, STO_LOWHIGH); h_atr = iATR(_Symbol, PERIOD_M1, InpATR_Period); h_ema20_m1 = iMA(_Symbol, PERIOD_M1, InpFastEMA, 0, MODE_EMA, PRICE_CLOSE); h_bb = iBands(_Symbol, PERIOD_M1, InpBB_Period, 0, InpBB_Dev, PRICE_CLOSE); // M5 指标句柄 h_ema20_m5 = iMA(_Symbol, PERIOD_M5, InpFastEMA, 0, MODE_EMA, PRICE_CLOSE); h_ema50_m5 = iMA(_Symbol, PERIOD_M5, InpSlowEMA, 0, MODE_EMA, PRICE_CLOSE); h_adx = iADX(_Symbol, PERIOD_M5, InpADX_Period); // M15 MACD h_macd_m15 = iMACD(_Symbol, PERIOD_M15, InpMACD_Fast, InpMACD_Slow, InpMACD_Signal, PRICE_CLOSE); if(h_rsi==INVALID_HANDLE || h_stoch==INVALID_HANDLE || h_atr==INVALID_HANDLE || h_bb==INVALID_HANDLE || h_adx==INVALID_HANDLE || h_macd_m15==INVALID_HANDLE) { Print("[QP] 指标初始化失败"); return(INIT_FAILED); } g_dayStartEquity = AccountInfoDouble(ACCOUNT_EQUITY); MqlDateTime dt; TimeCurrent(dt); g_lastDay = dt.day_of_year; return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { IndicatorRelease(h_rsi); IndicatorRelease(h_stoch); IndicatorRelease(h_atr); IndicatorRelease(h_ema20_m1); IndicatorRelease(h_ema20_m5); IndicatorRelease(h_ema50_m5); IndicatorRelease(h_macd_m15); IndicatorRelease(h_bb); IndicatorRelease(h_adx); } //+------------------------------------------------------------------+ void OnTick() { //--- 日切重置 MqlDateTime dt; TimeCurrent(dt); if(dt.day_of_year != g_lastDay) { g_dayStartEquity = AccountInfoDouble(ACCOUNT_EQUITY); g_lastDay = dt.day_of_year; g_consecLosses = 0; } //--- 日内风控 double equity = AccountInfoDouble(ACCOUNT_EQUITY); double dailyPnL = equity - g_dayStartEquity; if(dailyPnL < -(g_dayStartEquity * InpDailyLossLimit / 100.0)) { CloseAllPositions(); return; } if(TimeCurrent() < g_pauseUntil) return; if(dt.hour < InpStartHour || dt.hour >= InpEndHour) return; ManagePositions(); //--- 新K线检测 static datetime lastBar = 0; datetime curBar = iTime(_Symbol, PERIOD_M1, 0); if(curBar == lastBar) return; lastBar = curBar; if(CountPositions() >= InpMaxOpenTrades) return; //--- 读取指标数据 double rsi[], stK[], stD[], atr[], ema20_m1[]; double ema20_m5[], ema50_m5[], adx[], macd[]; double bbUp[], bbLow[], bbMid[]; CopyBuffer(h_rsi, 0, 1, 3, rsi); CopyBuffer(h_stoch, MAIN_LINE, 1, 3, stK); CopyBuffer(h_stoch, SIGNAL_LINE, 1, 3, stD); CopyBuffer(h_atr, 0, 1, 3, atr); CopyBuffer(h_ema20_m1, 0, 1, 2, ema20_m1); CopyBuffer(h_ema20_m5, 0, 1, 2, ema20_m5); CopyBuffer(h_ema50_m5, 0, 1, 2, ema50_m5); CopyBuffer(h_adx, MAIN_LINE, 1, 2, adx); CopyBuffer(h_macd_m15, MAIN_LINE, 1, 3, macd); CopyBuffer(h_bb, BASE_LINE, 1, 2, bbMid); CopyBuffer(h_bb, UPPER_BAND, 1, 2, bbUp); CopyBuffer(h_bb, LOWER_BAND, 1, 2, bbLow); ArraySetAsSeries(rsi,true); ArraySetAsSeries(stK,true); ArraySetAsSeries(stD,true); ArraySetAsSeries(atr,true); ArraySetAsSeries(ema20_m1,true); ArraySetAsSeries(ema20_m5,true); ArraySetAsSeries(ema50_m5,true); ArraySetAsSeries(adx,true); ArraySetAsSeries(macd,true); ArraySetAsSeries(bbUp,true); ArraySetAsSeries(bbLow,true); ArraySetAsSeries(bbMid,true); double close1 = iClose(_Symbol, PERIOD_M1, 1); double bbWidth = (bbMid[0] > 0) ? (bbUp[0] - bbLow[0]) / bbMid[0] : 0; // BB带宽均值 (简化:与当前对比) double bbWidth1 = (bbMid[1] > 0) ? (bbUp[1] - bbLow[1]) / bbMid[1] : 0; bool bbExpanding = (bbWidth > bbWidth1); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); //=============== LONG =============== bool L1 = (rsi[1] < 25 && rsi[0] > InpRSI_OversoldExit); bool L2 = (stK[1] < stD[1] && stK[0] > stD[0] && stK[0] < 40); bool L3 = (close1 > ema20_m1[0] + InpATR_Mult * atr[0]); bool L4 = (ema20_m5[0] > ema50_m5[0]); bool L5 = (macd[0] > 0 && macd[0] > macd[1]); bool L6 = bbExpanding; bool L7 = (adx[0] > InpADX_Min); if(L1 && L2 && L3 && L4 && L5 && L6 && L7) { double sl = ask - InpSL_ATR_Mult * atr[0]; double tp = ask + InpTP1_ATR_Mult * atr[0]; double lots = CalcLots(InpSL_ATR_Mult * atr[0]); lots = AdjustLots(lots); if(lots > 0) trade.Buy(lots, _Symbol, ask, NormalizeDouble(sl, _Digits), NormalizeDouble(tp, _Digits), "QP_Long"); } //=============== SHORT =============== bool S1 = (rsi[1] > 75 && rsi[0] < InpRSI_OverboughtExit); bool S2 = (stK[1] > stD[1] && stK[0] < stD[0] && stK[0] > 60); bool S3 = (close1 < ema20_m1[0] - InpATR_Mult * atr[0]); bool S4 = (ema20_m5[0] < ema50_m5[0]); bool S5 = (macd[0] < 0 && macd[0] < macd[1]); bool S6 = bbExpanding; bool S7 = (adx[0] > InpADX_Min); if(S1 && S2 && S3 && S4 && S5 && S6 && S7) { double sl = bid + InpSL_ATR_Mult * atr[0]; double tp = bid - InpTP1_ATR_Mult * atr[0]; double lots = CalcLots(InpSL_ATR_Mult * atr[0]); lots = AdjustLots(lots); if(lots > 0) trade.Sell(lots, _Symbol, bid, NormalizeDouble(sl, _Digits), NormalizeDouble(tp, _Digits), "QP_Short"); } } //+------------------------------------------------------------------+ double CalcLots(double stopDist) { double riskMoney = AccountInfoDouble(ACCOUNT_EQUITY) * InpRiskPercent / 100.0; double tickVal = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); if(tickSize == 0 || tickVal == 0) return(0); double lots = riskMoney / ((stopDist / tickSize) * tickVal); double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX); double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); lots = MathFloor(lots / lotStep) * lotStep; lots = MathMax(minLot, MathMin(maxLot, lots)); double capLots = AccountInfoDouble(ACCOUNT_EQUITY) / 5000.0; lots = MathMin(lots, capLots); return(NormalizeDouble(lots, 2)); } double AdjustLots(double lots) { if(g_consecLosses >= InpConsecLossPause) { g_pauseUntil = TimeCurrent() + 3600; g_consecLosses = 0; return(0); } if(g_consecLosses >= InpConsecLossHalf) lots *= 0.5; return(lots); } int CountPositions() { int cnt = 0; for(int i = PositionsTotal()-1; i >= 0; i--) if(posInfo.SelectByIndex(i) && posInfo.Magic() == InpMagicNumber && posInfo.Symbol() == _Symbol) cnt++; return(cnt); } void ManagePositions() { double atrBuf[]; CopyBuffer(h_atr, 0, 1, 1, atrBuf); double curATR = atrBuf[0]; for(int i = PositionsTotal()-1; i >= 0; i--) { if(!posInfo.SelectByIndex(i)) continue; if(posInfo.Magic() != InpMagicNumber || posInfo.Symbol() != _Symbol) continue; double openPrice = posInfo.PriceOpen(); int barsHeld = (int)((TimeCurrent() - posInfo.Time()) / 60); double curSL = posInfo.StopLoss(); if(posInfo.PositionType() == POSITION_TYPE_BUY) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double profit = bid - openPrice; // 时间止损 if(barsHeld >= InpMaxBarsHold && profit < curATR) { trade.PositionClose(posInfo.Ticket()); continue; } // 跟踪止损 if(profit >= curATR) { double newSL = bid - InpTrail_ATR_Mult * curATR; if(newSL > curSL) trade.PositionModify(posInfo.Ticket(), NormalizeDouble(newSL, _Digits), posInfo.TakeProfit()); } } else { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double profit = openPrice - ask; if(barsHeld >= InpMaxBarsHold && profit < curATR) { trade.PositionClose(posInfo.Ticket()); continue; } if(profit >= curATR) { double newSL = ask + InpTrail_ATR_Mult * curATR; if(newSL < curSL || curSL == 0) trade.PositionModify(posInfo.Ticket(), NormalizeDouble(newSL, _Digits), posInfo.TakeProfit()); } } } } void CloseAllPositions() { for(int i = PositionsTotal()-1; i >= 0; i--) { if(posInfo.SelectByIndex(i) && posInfo.Magic() == InpMagicNumber && posInfo.Symbol() == _Symbol) trade.PositionClose(posInfo.Ticket()); } } //+------------------------------------------------------------------+
{QuantumPulse™ 多周期微结构共振信号指标} {适用周期: 1分钟/5分钟} {========== 引擎A: 动量脉冲检测 ==========} RSI5:=RSI(CLOSE,5); PREV_RSI5:=REF(RSI5,1); RSI_LONG:=PREV_RSI5<25 AND RSI5>30; RSI_SHORT:=PREV_RSI5>75 AND RSI5<70; STOCH_K:=SMA(RSV(5),3,1); STOCH_D:=SMA(STOCH_K,3,1); PREV_K:=REF(STOCH_K,1); PREV_D:=REF(STOCH_D,1); KD_LONG:=PREV_K<PREV_D AND STOCH_K>STOCH_D AND STOCH_K<40; KD_SHORT:=PREV_K>PREV_D AND STOCH_K<STOCH_D AND STOCH_K>60; {ATR通道突破} ATR14:=MA(TR,14); EMA20:=EMA(CLOSE,20); ATR_LONG:=CLOSE>EMA20+1.2*ATR14; ATR_SHORT:=CLOSE<EMA20-1.2*ATR14; {========== 引擎C: 自适应过滤 ==========} BB_MID:=MA(CLOSE,20); BB_STD:=STD(CLOSE,20); BB_UP:=BB_MID+2*BB_STD; BB_LOW:=BB_MID-2*BB_STD; BB_WIDTH:=(BB_UP-BB_LOW)/BB_MID*100; BB_AVG:=MA(BB_WIDTH,20); VOL_EXPAND:=BB_WIDTH>BB_AVG; {ADX趋势确认} MTR:=MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(LOW-REF(CLOSE,1))); HD:=HIGH-REF(HIGH,1); LD:=REF(LOW,1)-LOW; DMP:=SMA(IF(HD>0 AND HD>LD,HD,0),14,1); DMM:=SMA(IF(LD>0 AND LD>HD,LD,0),14,1); PDI:=DMP/SMA(MTR,14,1)*100; MDI:=DMM/SMA(MTR,14,1)*100; ADX14:=SMA(ABS(PDI-MDI)/(PDI+MDI)*100,14,1); TREND_OK:=ADX14>20; {========== 综合信号 ==========} BUY_SIGNAL:=RSI_LONG AND KD_LONG AND ATR_LONG AND VOL_EXPAND AND TREND_OK; SELL_SIGNAL:=RSI_SHORT AND KD_SHORT AND ATR_SHORT AND VOL_EXPAND AND TREND_OK; {========== 图表绘制 ==========} STOCH_K_LINE:STOCH_K,COLORWHITE,LINETHICK1; STOCH_D_LINE:STOCH_D,COLORYELLOW,LINETHICK1; RSI_LINE:RSI5,COLORCYAN,LINETHICK1; {买卖信号标记} DRAWICON(BUY_SIGNAL,LOW-ATR14*0.5,1); DRAWICON(SELL_SIGNAL,HIGH+ATR14*0.5,2); {止损参考线} SL_LONG:=IF(BUY_SIGNAL,CLOSE-1.5*ATR14,DRAWNULL),COLORGREEN,POINTDOT; SL_SHORT:=IF(SELL_SIGNAL,CLOSE+1.5*ATR14,DRAWNULL),COLORRED,POINTDOT; {TP参考线} TP_LONG:=IF(BUY_SIGNAL,CLOSE+1.5*ATR14,DRAWNULL),COLORMAGENTA,POINTDOT; TP_SHORT:=IF(SELL_SIGNAL,CLOSE-1.5*ATR14,DRAWNULL),COLORMAGENTA,POINTDOT; {波动率面板} VOL_STATUS:=IF(VOL_EXPAND,1,0),COLORRED,NODRAW; ADX_STATUS:=IF(ADX14>20,1,0),COLORRED,NODRAW;
| 项目 | 内容 | 说明 |
|---|---|---|
| 日期标识 | YYYYMMDD_QP_DayN | 按自然日递增,保证不重复 |
| 当日参数微调 | 基于前一日 ATR 均值动态调整 ATR_Mult | 高波动日 Mult ×1.2, 低波动日 ×0.8 |
| 品种优先级 | 按前日波动率/流动性评分排序 | 前 3 名品种重点监控 |
| 重大事件预警 | NFP / CPI / FOMC 等发布时间 | 事件前后 15min 自动暂停 |
| 前日回顾 | 胜率/盈亏比/最大回撤/夏普比率 | 与历史均值对比 |
| 策略状态 | ACTIVE / REDUCED / PAUSED | 根据周度风控状态判定 |