#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_"开头的对象
} |