设为首页 收藏本站 切换语言

MQL4指标编写框架代码结构

| 发表于 2025-3-7 14:25:26 | 显示全部楼层 |复制链接
非农前无事,看有人想学MT4代码。虽然我也半桶水,那就写个框架,方便新人朋友们学习。
========================
代码结构说明:
  • 属性声明区 (#property)

    • 定义指标显示位置、缓冲区数量、图形样式等基础属性

  • 输入参数区 (input)

    • 用户可调整的外部参数,自动生成属性对话框

  • 全局变量区

    • 指标缓冲区声明
    • 计算用辅助变量

  • 初始化函数 (OnInit)

    • 绑定缓冲区
    • 设置图形属性
    • 参数有效性检查
    • 初始化计算变量

  • 核心计算函数 (OnCalculate)

    • 主数据处理循环
    • 新旧数据区分处理
    • 指标核心算法实现位置

  • 自定义函数区

    • 封装复杂计算逻辑
    • 提高代码可读性和复用性

  • 清理函数 (OnDeinit)

    • 释放资源
    • 删除图形对象

使用建议:
  • 复制此框架创建新指标
  • 在OnCalculate中实现核心算法
  • 通过添加/修改input参数增加可配置项
  • 使用自定义函数封装复杂逻辑
  • 根据需求修改缓冲区数量和图形类型

注意事项:
  • 数组访问时注意越界检查
  • 使用EMPTY_VALUE处理空值显示
  • 合理处理prev_calculated以提高效率
  • 多周期调用时注意同步问题
  • 建议使用iCustom()调用其他指标

测试时建议:
  • 在策略测试器中验证基础逻辑
  • 使用Print()函数输出调试信息
  • 逐步增加复杂度,分阶段测试
  • 检查内存使用情况防止泄漏

举报

评论 使用道具

精彩评论4

过去了
DD
 楼主 | 发表于 2025-3-7 14:26:26 | 显示全部楼层
关键要素注释说明:

    缓冲区系统:
    每个SetIndexBuffer()绑定的数组对应一个图形输出
    EMPTY_VALUE用于控制不显示数据点
    数组是动态的,大小自动匹配图表柱数
    OnCalculate参数:
    rates_total:当前可用的总柱数
    prev_calculated:上次已计算的柱数(用于增量计算)
    价格数组是时间序列,索引0对应最新柱
    效率优化技巧:
    start_pos变量避免重复计算历史数据
    增量计算:prev_calculated > 0时只处理新数据
    绘图特性:
    SetIndexArrow()使用Wingdings字体代码(233=上箭头)
    Point变量表示当前品种的最小价格单位
    错误处理:
    在OnInit中进行参数有效性检查
    使用Alert()函数输出错误信息
    内存管理:
    OnDeinit中删除创建的图形对象
    动态数组由平台自动管理
使用建议补充:
    在复杂计算时,建议使用ArraySetAsSeries()设置数组方向
    高频计算时使用IndicatorCounted()代替prev_calculated(旧版兼容)
    调试时可添加Comment()函数在图表显示实时数据
举报

点赞 评论 使用道具

过去了
DD
 楼主 | 发表于 2025-3-7 14:27:00 | 显示全部楼层
开始,啥也别想,框架就是必须有的东西。这和建房子一样。不要置疑。
举报

点赞 评论 使用道具

过去了
DD
 楼主 | 发表于 2025-3-7 14:28:22 | 显示全部楼层
#property copyright "Copyright 2024, YourNameHere"  // 版权声明(显示在属性窗口)
#property link      "https://www.yoursite"         // 作者链接(点击可访问)
#property version   "1.00"                         // 指标版本号
//---- 指标属性设置---------------------------------------------
#property indicator_chart_window       // 指标显示在主图窗口
//#property indicator_separate_window // 如果取消注释,指标显示在独立窗口
#property indicator_buffers 2          // 声明使用的缓冲区数量(每个图形元素需要一个缓冲区)
#property indicator_color1 clrRed      // 第一个缓冲区的显示颜色
#property indicator_color2 clrBlue     // 第二个缓冲区的显示颜色
#property indicator_width1 2           // 第一个缓冲区的线宽(1-5)
#property indicator_type1 DRAW_LINE    // 第一个缓冲区的绘制类型:连续线
//#property indicator_type2 DRAW_ARROW // 第二个缓冲区的绘制类型示例(箭头)
//---- 输入参数(外部可调参数)----------------------------------
input int      InpPeriod = 14;         // [参数] 计算周期(整数型参数)
input double   InpDeviation = 2.0;     // [参数] 标准差倍数(浮点型参数)
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // [参数] 价格类型枚举
//---- 全局变量------------------------------------------------
double Buffer1[];                     // 主数据缓冲区数组(动态数组)
double Buffer2[];                     // 辅助数据缓冲区数组
int    calc_begin;                    // 计算起始位置变量
//+------------------------------------------------------------------+
//| 自定义初始化函数                                                  |
//+------------------------------------------------------------------+
int OnInit()  // 指标初始化入口函数(必须存在)
{
   //---- 指标绑定缓冲区
   SetIndexBuffer(0, Buffer1);         // 将缓冲区数组绑定到索引0(第一个图形)
   SetIndexBuffer(1, Buffer2);         // 将缓冲区数组绑定到索引1(第二个图形)

   //---- 设置第一个缓冲区的显示属性
   SetIndexStyle(0, DRAW_LINE);        // 设置索引0的绘制方式为连续线
   SetIndexLabel(0, "Main Line");      // 在数据窗口显示的名称
   SetIndexShift(0, 0);                // 设置显示偏移(0表示不偏移)

   //---- 设置第二个缓冲区的显示属性(示例)
   SetIndexStyle(1, DRAW_ARROW);       // 设置索引1的绘制方式为箭头
   SetIndexLabel(1, "Signal Arrow");   // 在数据窗口显示的名称
   SetIndexArrow(1, 233);              // 设置箭头符号(来自Wingdings字体)

   //---- 计算起始位置设置
   calc_begin = InpPeriod;             // 设置计算起点(避免访问不存在的历史数据)

   //---- 初始化有效性检查
   if(InpPeriod <= 0)                  // 检查输入参数是否合法
   {
      Alert("错误:周期参数必须大于0");  // 弹出错误提示
      return(INIT_FAILED);             // 返回初始化失败状态
   }
   
   //---- 设置指标短名称(显示在图表左上角)
   IndicatorShortName("MyIndicator(" + string(InpPeriod) + ")");
   
   return(INIT_SUCCEEDED);            // 返回初始化成功状态
}

//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,          // 当前可用柱数
                const int prev_calculated,      // 前次已处理柱数
                const datetime &time[],         // 时间数组
                const double &open[],           // 开盘价数组
                const double &high[],           // 最高价数组
                const double &low[],            // 最低价数组
                const double &close[],          // 收盘价数组
                const long &tick_volume[],      // 跳动量数组
                const long &volume[],           // 交易量数组
                const int &spread[])            // 点差数组
{
   //---- 处理首次计算或数据变化(例如新增柱)
   if(prev_calculated == 0)
   {
      // 初始化历史数据(将缓冲区值设为空)
      ArrayInitialize(Buffer1, EMPTY_VALUE);
      ArrayInitialize(Buffer2, EMPTY_VALUE);
   }

   //---- 确定计算起始位置
   int start_pos = (prev_calculated > 0) ? prev_calculated - 1 : 0;
   
   //---- 主计算循环(遍历所有需要计算的柱)
   for(int i=start_pos; i<rates_total; i++)
   {
      // 示例计算逻辑(实际需要替换为有效算法)
      // 这里调用iCustom示例(实际应替换为真实计算)
      Buffer1[i] = iCustom(NULL, 0, "Example", InpPeriod, 0, i);
      
      // 信号生成逻辑示例(当主线上穿时显示箭头)
      if(i > 0 && Buffer1[i] > Buffer1[i-1])
         Buffer2[i] = low[i] - 10*Point;  // 在K线下方10点显示箭头
      else
         Buffer2[i] = EMPTY_VALUE;        // 不满足条件时设为空值
   }

   //---- 返回已处理的数据总量(告知平台处理进度)
   return(rates_total);
}

//+------------------------------------------------------------------+
//| 自定义计算函数示例                                                |
//+------------------------------------------------------------------+
double CustomCalculation(int index)  // 自定义函数示例
{
   // 示例:计算中间价(可根据需要修改)
   return (close[index] + open[index]) / 2;
}

//+------------------------------------------------------------------+
//| 去初始化函数                                                     |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)  // 指标移除时自动调用
{
   // 清理工作:删除本指标创建的所有图形对象
   ObjectsDeleteAll(0, "MyIndicator_");  // 删除名称以"MyIndicator_"开头的对象
}
举报

点赞 评论 使用道具

wangddtt
CC
| 发表于 6 天前 | 显示全部楼层
说的真详细,简单易懂…………
举报

点赞 评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册

简体中文
繁體中文
English(英语)
日本語(日语)
Deutsch(德语)
Русский язык(俄语)
بالعربية(阿拉伯语)
Türkçe(土耳其语)
Português(葡萄牙语)
ภาษาไทย(泰国语)
한어(朝鲜语/韩语)
Français(法语)