希望祠.同舟.量化.侦云取势势能研究中心

 找回密码
 立即注册

《周易.系辞》

君子藏器于身,待时而动!

《吕氏.春秋》

君子谋时而动,顺势而为!

《晏子·霸业因时而生》

识时务者为俊杰,通机变者为英豪!

《周易.系辞》

天之所助,吉无不利,天之所助者.顺天者也!

《史记.太史公自序》
天之势,浩浩汤汤,顺之者昌,逆之者亡!

《寒窑赋》

天不得时,日月无光.地 不得时,草木不长.

《周易.系辞》

刚柔者,立本者也!变通者,识时者也!

圣人云:

君子务本,本立而道生!

 《势胜学》

不知势,无以为人也.势易而未觉,必败焉!

《周易·系辞上传》:

富有之谓大业,日新之谓盛德!

《礼记.大学》:
格物致知,正心诚意,修身齐家!

《礼记.中庸》:

凡事预则立,不预则废!

查看: 2522|回复: 0

[【优秀推荐】曲线完美收益中等] 通道周期突破策略

[复制链接]

1656

主题

1894

帖子

1万

积分

版主

Rank: 7Rank: 7Rank: 7

积分
11937

最佳新人活跃会员热心会员推广达人宣传达人荣誉版主勋章理事

QQ
侦云取势 发表于 2025-4-9 12:05:45 | 显示全部楼层 |阅读模式
//+------------------------------------------------------------------+
//|                                                   ChannelPRO.mq5 |
//|                                  Professionally Enhanced by AI   |
//|                                              https://www.example.com |
//+------------------------------------------------------------------+
#property copyright "AI Forex Expert"
#property version   "2.2"
#property description "Advanced Channel Breakout System"
input int      ChannelPeriod = 20;         // 通道周期
input double   ATRMultiplier = 1.5;        // ATR止损倍数
input int      TrendMAPeriod = 200;        // 趋势MA周期
input double   RiskPercent   = 1.0;        // 风险百分比
input int      ADXPeriod     = 14;         // ADX周期
input int      ADXThreshold  = 25;         // ADX强度阈值
input int      MaxSpread     = 20;         // 最大允许点差
int            adxHandle;
int            maHandle;
int            atrHandle;
double         upperChannel, lowerChannel;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   maHandle = iMA(_Symbol, _Period, TrendMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
   adxHandle = iADX(_Symbol, _Period, ADXPeriod);
   atrHandle = iATR(_Symbol, _Period, 14);
   if(maHandle == INVALID_HANDLE || adxHandle == INVALID_HANDLE || atrHandle == INVALID_HANDLE)
   {
      Alert("指标初始化失败!");
      return(INIT_FAILED);
   }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 计算动态通道函数                                                 |
//+------------------------------------------------------------------+
void CalculateChannel()
{
   double highArray[], lowArray[];
   ArraySetAsSeries(highArray, true);
   ArraySetAsSeries(lowArray, true);
   if(CopyHigh(_Symbol, _Period, 1, ChannelPeriod, highArray) != ChannelPeriod ||
      CopyLow(_Symbol, _Period, 1, ChannelPeriod, lowArray) != ChannelPeriod)
   {
      Print("获取价格数据失败!");
      return;
   }
   upperChannel = highArray[ArrayMaximum(highArray)];
   lowerChannel = lowArray[ArrayMinimum(lowArray)];
   if(upperChannel <= lowerChannel)
   {
      Print("无效通道值!");
      upperChannel = 0;
      lowerChannel = 0;
   }
}
//+------------------------------------------------------------------+
//| 趋势方向判断函数                                                 |
//+------------------------------------------------------------------+
bool IsBullishTrend()
{
   double maArray[2], closeArray[2];
   if(CopyBuffer(maHandle, 0, 0, 2, maArray) != 2 ||
      CopyClose(_Symbol, _Period, 0, 2, closeArray) != 2)
   {
      Print("趋势判断数据获取失败");
      return false;
   }
   return (closeArray[1] > maArray[1] && closeArray[0] > maArray[0]);
}
bool IsBearishTrend()
{
   double maArray[2], closeArray[2];
   if(CopyBuffer(maHandle, 0, 0, 2, maArray) != 2 ||
      CopyClose(_Symbol, _Period, 0, 2, closeArray) != 2)
   {
      Print("趋势判断数据获取失败");
      return false;
   }
   return (closeArray[1] < maArray[1] && closeArray[0] < maArray[0]);
}
//+------------------------------------------------------------------+
//| 获取ADX强度值                                                    |
//+------------------------------------------------------------------+
double GetADXValue()
{
   double adxArray[1];
   if(CopyBuffer(adxHandle, 0, 0, 1, adxArray) != 1)
   {
      Print("ADX值获取失败");
      return 0;
   }
   return adxArray[0];
}
//+------------------------------------------------------------------+
//| 计算头寸规模函数                                                 |
//+------------------------------------------------------------------+
double CalculateLotSize(double stopLossPoints)
{
   if(stopLossPoints <= 0) return 0;
   double balance = AccountInfoDouble(ACCOUNT_BALANCE);
   double riskAmount = balance * RiskPercent / 100;
   double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
   double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
   double lots = riskAmount / (stopLossPoints * tickValue);
   lots = floor(lots / lotStep) * lotStep;
   return NormalizeDouble(lots, 2);
}
//+------------------------------------------------------------------+
//| 执行交易操作函数                                                 |
//+------------------------------------------------------------------+
bool ExecuteTrade(ENUM_ORDER_TYPE tradeType)
{
   if(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) > MaxSpread * 10)
   {
      Print("点差过大,取消交易");
      return false;
   }
   double atrValue[1], currentClose[1];
   if(CopyBuffer(atrHandle, 0, 0, 1, atrValue) != 1 ||
      CopyClose(_Symbol, _Period, 0, 1, currentClose) != 1)
   {
      Print("交易数据获取失败");
      return false;
   }
   double sl = 0, tp = 0;
   double price = tradeType == ORDER_TYPE_BUY ? SymbolInfoDouble(_Symbol, SYMBOL_ASK)
                                             : SymbolInfoDouble(_Symbol, SYMBOL_BID);
   if(tradeType == ORDER_TYPE_BUY)
   {
      sl = lowerChannel - atrValue[0] * ATRMultiplier;
      sl = NormalizeDouble(sl, _Digits);
      tp = price + (price - sl) * 2;
      tp = NormalizeDouble(tp, _Digits);
   }
   else
   {
      sl = upperChannel + atrValue[0] * ATRMultiplier;
      sl = NormalizeDouble(sl, _Digits);
      tp = price - (sl - price) * 2;
      tp = NormalizeDouble(tp, _Digits);
   }
   double stopLossPoints = MathAbs(price - sl) / _Point;
   double lots = CalculateLotSize(stopLossPoints);
   MqlTradeRequest request = {};
   request.action    = TRADE_ACTION_DEAL;
   request.symbol    = _Symbol;
   request.volume    = lots;
   request.type      = tradeType;
   request.price     = price;
   request.sl        = sl;
   request.tp        = tp;
   request.deviation = 5;
   request.type_filling = ORDER_FILLING_FOK;
   MqlTradeResult result;
   if(!OrderSend(request, result))
   {
      int errorCode = GetLastError();
      PrintFormat("订单发送失败 错误 %d: %s", errorCode, GetErrorDescription(errorCode)); // 关键修正点
      return false;
   }
   if(result.retcode != TRADE_RETCODE_DONE)
   {
      PrintFormat("交易执行失败 代码 %d: %s", result.retcode, GetRetcodeID(result.retcode));
      return false;
   }
   PrintFormat("成功开立 %s 订单 手数: %.2f 价格: %.5f",
               EnumToString(tradeType),
               result.volume,
               result.price);
   return true;
}
//+------------------------------------------------------------------+
//| 主执行函数                                                      |
//+------------------------------------------------------------------+
void OnTick()
{
   if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
   {
      Alert("自动交易未启用!");
      return;
   }
   if(Bars(_Symbol, _Period) < ChannelPeriod + 50)
   {
      Print("可用数据不足");
      return;
   }
   CalculateChannel();
   double adxValue = GetADXValue();
   bool bullish = IsBullishTrend();
   bool bearish = IsBearishTrend();
   double currentClose[1];
   if(CopyClose(_Symbol, _Period, 0, 1, currentClose) != 1)
   {
      Print("当前价格获取失败");
      return;
   }
   bool buySignal = currentClose[0] > upperChannel && bullish && adxValue > ADXThreshold;
   bool sellSignal = currentClose[0] < lowerChannel && bearish && adxValue > ADXThreshold;
   bool hasPosition = false;
   if(PositionSelect(_Symbol))
   {
      ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      hasPosition = (positionType == POSITION_TYPE_BUY) || (positionType == POSITION_TYPE_SELL);
   }
   if(!hasPosition)
   {
      if(buySignal)
      {
         ExecuteTrade(ORDER_TYPE_BUY);
      }
      else if(sellSignal)
      {
         ExecuteTrade(ORDER_TYPE_SELL);
      }
   }
}
//+------------------------------------------------------------------+
//| 错误代码描述函数(新增关键函数)                                |
//+------------------------------------------------------------------+
string GetErrorDescription(int errorCode)
{
   switch(errorCode)
   {
      case 0:     return "操作成功";
      case 1:     return "没有错误,但结果未知";
      case 2:     return "通用错误";
      case 3:     return "无效参数";
      case 4:     return "交易服务器忙";
      case 5:     return "旧版本客户端";
      case 6:     return "没有连接";
      case 7:     return "权限不足";
      case 8:     return "请求太频繁";
      case 9:     return "交易操作被拒绝";
      case 64:    return "账户被禁用";
      case 65:    return "无效账户";
      case 128:   return "交易超时";
      case 129:   return "无效价格";
      case 130:   return "无效止损";
      case 131:    return "无效交易量";
      case 132:    return "市场已关闭";
      case 133:    return "交易被禁用";
      case 134:    return "资金不足";
      case 135:    return "价格已变化";
      case 136:    return "没有报价";
      case 137:    return "经纪商繁忙";
      case 138:    return "重新报价";
      case 139:    return "订单被锁定";
      case 140:    return "只允许买入";
      case 141:    return "尝试次数过多";
      case 145:    return "修改被拒绝,因为订单太接近市场";
      case 146:    return "交易环境繁忙";
      case 147:    return "止损参数错误";
      case 148:    return "订单数量过多";
      default:     return "未知错误";
   }
}
//+------------------------------------------------------------------+
//| 交易返回码描述函数                                              |
//+------------------------------------------------------------------+
string GetRetcodeID(int retcode)
{
   switch(retcode)
   {
      case 10004: return "TRADE_RETCODE_DONE";
      case 10006: return "TRADE_RETCODE_REJECT";
      case 10007: return "TRADE_RETCODE_CANCEL";
      case 10008: return "TRADE_RETCODE_PLACED";
      case 10009: return "TRADE_RETCODE_DONE_PARTIAL";
      case 10010: return "TRADE_RETCODE_ERROR";
      case 10011: return "TRADE_RETCODE_TIMEOUT";
      case 10012: return "TRADE_RETCODE_INVALID";
      case 10013: return "TRADE_RETCODE_INVALID_VOLUME";
      case 10014: return "TRADE_RETCODE_INVALID_PRICE";
      case 10015: return "TRADE_RETCODE_INVALID_STOPS";
      case 10016: return "TRADE_RETCODE_TRADE_DISABLED";
      case 10017: return "TRADE_RETCODE_MARKET_CLOSED";
      case 10018: return "TRADE_RETCODE_NO_MONEY";
      case 10019: return "TRADE_RETCODE_PRICE_CHANGED";
      case 10020: return "TRADE_RETCODE_PRICE_OFF";
      case 10021: return "TRADE_RETCODE_INVALID_EXPIRATION";
      case 10022: return "TRADE_RETCODE_ORDER_CHANGED";
      case 10023: return "TRADE_RETCODE_TOO_MANY_REQUESTS";
      case 10024: return "TRADE_RETCODE_NO_CHANGES";
      case 10025: return "TRADE_RETCODE_SERVER_DISABLES_AT";
      case 10026: return "TRADE_RETCODE_CLIENT_DISABLES_AT";
      case 10027: return "TRADE_RETCODE_LOCKED";
      case 10028: return "TRADE_RETCODE_FROZEN";
      case 10029: return "TRADE_RETCODE_INVALID_FILL";
      case 10030: return "TRADE_RETCODE_CONNECTION";
      case 10031: return "TRADE_RETCODE_ONLY_REAL";
      case 10032: return "TRADE_RETCODE_LIMIT_ORDERS";
      case 10033: return "TRADE_RETCODE_LIMIT_VOLUME";
      default:    return "未知错误";
   }
}
//+------------------------------------------------------------------+
参数说明表格:
参数分类
参数名称
取值范围
默认值
说明

核心策略
ChannelPeriod10-10020通道计算周期
ATRMultiplier
0.5-5.01.5止损ATR倍数
TrendMAPeriod
50-500200趋势判断EMA周期
风险管理
RiskPercent0.1-5.01.0单笔交易风险比例
MaxDailyTrades
0-10010每日最大交易次数
MaxDrawdown
0-10020.0账户最大回撤限制(%)
时间控制
TradeStartHour0-238允许交易开始时间
TradeEndHour
0-2320允许交易结束时间
移动止损
TrailATRMultiple1.0-5.02.0移动止损ATR倍数
TrailStep
10-20050止损移动步长(点)
订单执行
Slippage0-503最大允许滑点
FillType
-FOK订单执行方式
[size=16.002px]使用说明:
  • 参数优化建议
    • 趋势市场:增大ChannelPeriod(25-30),降低ADXThreshold(22-25)
    • 震荡市场:减小ChannelPeriod(15-20),提高ADXThreshold(27-30)
    • 高风险策略:RiskPercent(2.0-3.0) + ATRMultiplier(1.0-1.2)
    • 保守策略:RiskPercent(0.5-1.0) + ATRMultiplier(2.0-2.5)

  • 特殊功能启用
    • 时段过滤:设置UseTimeFilter=true并配置交易时段
    • 移动止损:设置UseTrailingStop=true并调整倍数和步长
    • 加仓功能:AllowMultiLots=true时自动按倍数加仓



观天之道,执天之行。
行胜于言,取时于天。

成功=艰苦劳动+正确方法+少说空话 --爱因斯坦
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /5 下一条

人生者,生存也。
生存所需,财(钱)官(权)也。
财自食伤(子孙福德爻)生,
印星生身荫护,官财印全,适合人间生存也。
若命缺财,缺官,则失去生存权。
一旦脱离父母养育,将天天面临,
从绝望中醒来,又从绝望中睡去。来去如烟!

Archiver|小黑屋|希望祠.同舟.量化

GMT+8, 2025-6-17 02:12 , Processed in 0.035030 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表