SYSTEM ACTIVE

QuantumPulse™

多维度微结构高频交易系统

6000%
目标年化收益
≤8%
单日最大回撤
200+
日均交易频次
2.8
目标盈亏比
68%
目标胜率
≤2%
单笔风险敞口

⚠ 极端重要 · 风险声明

年化 6000% 属于极端激进目标。此收益水平在实盘中极难持续实现,历史上仅极少数机构在特定时段达成过类似表现,且伴随极高爆仓风险。本系统提供的策略框架仅供技术研究与回测学习,并非投资建议。高频交易依赖超低延迟基础设施(co-location、FPGA等),零售环境下滑点与手续费将显著侵蚀收益。实盘前必须进行至少 6 个月以上的模拟盘验证。任何交易均存在全部本金亏损的可能,请仅用可承受损失的资金参与。

策略名称与核心理念

📡 核心理念

QuantumPulse™ 采用「多周期微结构共振 + 动量脉冲捕获 + 自适应波动率过滤」三重引擎架构。核心思想:在 M1/M5 级别捕捉由机构订单流驱动的短期价格脉冲(Pulse),通过量价背离、波动率突破、多时间框架确认三重过滤,在高概率窗口密集开仓,单笔利润薄但胜率高,依靠极高频次复利实现超额收益。

高频 HFT 微结构分析 多时间框架 动量脉冲 自适应波动率

⚙️ 三引擎架构

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。

XAUUSD EURUSD GBPUSD NAS100

💹 收益模型假设

日均 200 笔交易 × 68% 胜率 × 平均盈亏比 2.8:1 → 单日净期望值 +3.2%(扣除手续费与滑点后)。年化交易日 250 天,复利累积:(1.032)^250 ≈ 2580 倍。实际受限于容量瓶颈、极端行情暂停等因素。

⚠ 此为理论极限模型,实盘复利衰减率约 40-60%,实际预期需大幅下调。

完整交易逻辑

🟢 做多入场条件(全部满足)

序号条件参数周期
C1RSI(5) 从超卖区(<25)向上穿越 30RSI_Period=5, OversoldExit=30M1
C2Stochastic %K(5,3,3) 上穿 %D 且 %K < 40K=5, D=3, Slowing=3M1
C3当前价格突破上轨:Close > EMA(20) + 1.2 × ATR(14)EMA=20, ATR=14, Mult=1.2M1
C4M5 趋势确认:EMA(20) > EMA(50)FastEMA=20, SlowEMA=50M5
C5M15 MACD 柱状线 > 0 且递增Fast=12, Slow=26, Signal=9M15
C6Bollinger 带宽 > MA(带宽,20),即波动率处于扩张期BB_Period=20, BB_Dev=2M1
C7ADX(14) > 20,确认趋势存在ADX_Period=14M5
C8当前时间处于活跃交易时段15:00-23:00 GMT+8——

🔴 做空入场条件(全部满足)

序号条件参数周期
C1RSI(5) 从超买区(>75)向下穿越 70RSI_Period=5, OverboughtExit=70M1
C2Stochastic %K 下穿 %D 且 %K > 60K=5, D=3, Slowing=3M1
C3Close < EMA(20) - 1.2 × ATR(14)EMA=20, ATR=14, Mult=1.2M1
C4M5:EMA(20) < EMA(50)FastEMA=20, SlowEMA=50M5
C5M15 MACD 柱状线 < 0 且递减Fast=12, Slow=26, Signal=9M15
C6Bollinger 带宽 > MA(带宽,20)BB_Period=20, BB_Dev=2M1
C7ADX(14) > 20ADX_Period=14M5
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 信号,立即全部平仓。

📊 仓位计算公式

// 凯利公式变体 + 固定分数法混合
RiskAmount = AccountEquity × 0.02 // 账户净值的2%
StopDistance = 1.5 × ATR(14) // 止损距离(点数)
LotSize = RiskAmount / (StopDistance × TickValue) // 手数
MaxLots = Min(LotSize, AccountEquity / 5000) // 上限保护
// 连亏缩仓:连续3亏后手数×0.5,连续5亏后暂停交易1小时

完整风险控制体系

CRITICAL

单笔风控

每笔交易风险敞口严格限制在账户净值的 2% 以内,无例外。

最大单笔亏损≤ 2% NAV
硬止损距离1.5 × ATR(14)
最大持仓时间30 min
滑点预留2 pips
CRITICAL

日内风控

单日亏损触及阈值后自动停机,防止情绪化交易和黑天鹅连锁损失。

日最大亏损≤ 5% NAV
触发动作全平 + 停机24h
连亏3次后手数 × 0.5
连亏5次后暂停1小时
HIGH

周度/月度风控

更长周期的回撤保护,避免系统性策略失效造成不可逆损失。

周最大回撤≤ 12% NAV
月最大回撤≤ 20% NAV
触发动作手数降至25% + 人工审查
恢复条件模拟盘连续盈利5日
HIGH

相关性控制

多品种同时交易时,限制高相关品种的总敞口,避免集中风险。

同向最大仓位3 笔
高相关品种组≤ 1 笔/组
总持仓上限5 笔
保证金使用率≤ 30%
MEDIUM

波动率自适应

根据市场波动率动态调整参数,低波时收紧止损、高波时放宽或暂停。

ATR < 50% 均值暂停交易
ATR > 200% 均值手数 × 0.5
VIX > 35(股指类)暂停交易
重大数据发布前全平 + 暂停15min
MEDIUM

技术故障保护

网络中断、平台故障等极端场景的应对预案。

心跳检测5秒/次
断连动作服务端止损生效
价格数据缺失暂停新开仓
报价偏移 > 50pips暂停+告警

MT4 Expert Advisor 完整代码

MQL4 QuantumPulse_EA.mq4
//+------------------------------------------------------------------+
//| 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);
   }
}
//+------------------------------------------------------------------+

MT5 Expert Advisor 完整代码

MQL5 QuantumPulse_EA.mq5
//+------------------------------------------------------------------+
//| 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());
   }
}
//+------------------------------------------------------------------+

通达信指标公式

TDX Formula QuantumPulse_Signal.tn6
{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;

策略执行流程图

📡 Market Tick 到达
日内 P&L ≤ -5% ?
→ YES →
🛑 全平 + 停机 24h
↓ NO
连亏暂停期 ?
→ YES →
⏳ 等待冷却期结束
↓ NO
活跃时段内 ?
→ NO →
⏸ 仅管理持仓
↓ YES
🔄 管理已有持仓
跟踪止损 / 时间止损 / 分批平仓
新 M1 K线 ?
→ NO →
等待下一 Tick
↓ YES
持仓 < MaxOpen ?
→ NO →
跳过信号检测
↓ YES
⚙️ 计算三引擎指标
Engine-A: RSI(5) + Stoch(5,3,3) + ATR通道
Engine-B: M5 EMA交叉 + M15 MACD
Engine-C: BB带宽 + ADX(14)
ATR > 50% 均值 ?
→ NO →
波动率过低, 跳过
↓ YES
C1-C8 全部满足 ?
(多/空方向独立判断)
↓ YES
📊 计算仓位
Risk% × Equity / (SL × TickVal)
连亏缩仓调整
🟢 BUY
SL: -1.5×ATR
TP1: +1.5×ATR (40%)
TP2: +2.5×ATR (30%)
Trail: 0.8×ATR (30%)
🔴 SELL
SL: +1.5×ATR
TP1: -1.5×ATR (40%)
TP2: -2.5×ATR (30%)
Trail: 0.8×ATR (30%)

模拟权益曲线(理论模型 · 仅供参考)

⏰ 每日 06:00 推送内容规范

项目内容说明
日期标识 YYYYMMDD_QP_DayN 按自然日递增,保证不重复
当日参数微调 基于前一日 ATR 均值动态调整 ATR_Mult 高波动日 Mult ×1.2, 低波动日 ×0.8
品种优先级 按前日波动率/流动性评分排序 前 3 名品种重点监控
重大事件预警 NFP / CPI / FOMC 等发布时间 事件前后 15min 自动暂停
前日回顾 胜率/盈亏比/最大回撤/夏普比率 与历史均值对比
策略状态 ACTIVE / REDUCED / PAUSED 根据周度风控状态判定