//+------------------------------------------------------------------+
//| 远山Ai量化--超级趋势变色版.mq4 |
//| Copyright 2025, 远山Ai量化 |
//| https://www.yuanshan.asia |
//+------------------------------------------------------------------+
#property copyright "远山Ai量化--制作于2025.4.06(点击此文字访问百款指标网站)"
#property link "https://www.yuanshan.asia"
#property version "1.00"
#property description "Ai量化编程,2小时学习,1分钟做策略/指标,微信:_yshan001(备注来意)"
#property description ""
#property description "远山Ai量化-超级趋势变色版 是一款判断当前趋势的指标,并根据趋势改变K线颜色"
#property indicator_chart_window
#property indicator_buffers 11 // 增加了4个用于K线颜色的缓冲区
// 默认颜色和样式(可通过代码动态修改)
#property indicator_color1 clrLime // 绿色上升趋势
#property indicator_color2 clrYellow // 黄色下降趋势
#property indicator_color3 clrLime // 绿色买入信号
#property indicator_color4 clrYellow // 黄色卖出信号
#property indicator_color5 clrLime // 绿色上升趋势点
#property indicator_color6 clrYellow // 黄色下降趋势点
#property indicator_color7 clrRed // K线上涨颜色
#property indicator_color8 clrBlue // K线下跌颜色
#property indicator_color9 clrRed // K线上涨颜色(实体)
#property indicator_color10 clrBlue // K线下跌颜色(实体)
#property indicator_color11 clrGray // 中性K线颜色
// 枚举:信号箭头类型
enum ENUM_SIGNAL_TYPE
{
SIGNAL_CIRCLE = 0, // 圆点
SIGNAL_ARROW_UPDOWN = 1, // 空心上下箭头
SIGNAL_ARROW_FILLED = 2, // 实心上下箭头
SIGNAL_ARROW_RIGHT = 3, // 实心向右箭头
SIGNAL_THUMB = 4, // 大拇指
SIGNAL_SUN = 5 // 太阳
};
// 枚举:趋势线样式
enum ENUM_TREND_STYLE
{
STYLE_LINES = 0, // 仅线段
STYLE_LINES_DOTS = 1, // 线段+圆点
STYLE_DOTS = 2 // 仅圆点
};
// 缓冲区声明
double TrendUp[]; // 上升趋势线
double TrendDown[]; // 下降趋势线
double BuySignal[]; // 买入信号
double SellSignal[]; // 卖出信号
double TrendUpDots[]; // 上升趋势圆点
double TrendDownDots[]; // 下降趋势圆点
double TrendBuffer[]; // 趋势方向缓冲区(用于计算)
// K线颜色缓冲区
double UpBar[]; // 上涨影线
double DownBar[]; // 下跌影线
double UpCandle[]; // 上涨实体
double DownCandle[]; // 下跌实体
// 指标参数
string TimeLabel = "══════ 指标到期时间 ══════"; // ▼ 指标到期信息
string ExpiryInfo = "2025年8月1日"; // [只读]指标到期时间
// 超级趋势计算参数
extern string ParamLabel1 = "══════ 趋势计算参数 ══════"; // ▼ 趋势计算参数
extern int ATR周期 = 10; // ATR周期
extern double 乘数系数 = 3.0; // ATR乘数
// 信号显示参数
extern string ParamLabel2 = "══════ 信号显示参数 ══════"; // ▼ 信号显示参数
extern bool 显示信号 = true; // 显示买卖信号
extern ENUM_SIGNAL_TYPE 信号类型 = SIGNAL_ARROW_RIGHT; // 信号类型
extern int 信号大小 = 1; // 信号大小
// 趋势线参数
extern string ParamLabel3 = "══════ 趋势线参数 ══════"; // ▼ 趋势线参数
extern ENUM_TREND_STYLE 趋势线样式 = STYLE_LINES; // 趋势线样式
extern int 线条粗细 = 1; // 趋势线粗细
extern int 点大小 = 1; // 趋势点大小
extern color 上升颜色 = clrLime; // 上升趋势颜色(绿色)
extern color 下降颜色 = clrYellow; // 下降趋势颜色(黄色)
// K线样式参数
extern string ParamLabel4 = "══════ K线样式参数 ══════"; // ▼ K线样式参数
extern color 上涨K线颜色 = clrBlue; // 上涨K线颜色
extern color 下跌K线颜色 = clrRed; // 下跌K线颜色
extern int K线影线宽度 = 1; // K线影线宽度
extern int K线实体宽度 = 3; // K线实体宽度
// 文字标签参数
extern string ParamLabel5 = "══════ 文字标签参数 ══════"; // ▼ 文字标签参数
extern bool 显示文字 = false; // 显示文字标签
extern string 买入文字 = "买入"; // 买入文字
extern string 卖出文字 = "卖出"; // 卖出文字
extern int 文字大小 = 10; // 文字大小
extern color 买入颜色 = clrLime; // 买入颜色(绿色)
extern color 卖出颜色 = clrYellow; // 卖出颜色(黄色)
extern int 文字偏移 = 10; // 文字偏移量(点)
// 全局变量
datetime expiry_date = D'2099.08.01 00:00'; // 到期时间
bool is_expired = false;
int g_text_size;
int buy_arrow_code, sell_arrow_code;
//+------------------------------------------------------------------+
//| 设置K线颜色函数 |
//+------------------------------------------------------------------+
void SetCandleColor(bool isUpTrend, int i)
{
// 重置所有缓冲区为空值
UpBar[i] = EMPTY_VALUE;
DownBar[i] = EMPTY_VALUE;
UpCandle[i] = EMPTY_VALUE;
DownCandle[i] = EMPTY_VALUE;
if(isUpTrend)
{
// 上涨K线
UpBar[i] = High[i];
UpCandle[i] = MathMax(Open[i], Close[i]);
DownBar[i] = Low[i];
DownCandle[i] = MathMin(Open[i], Close[i]);
}
else
{
// 下跌K线
DownBar[i] = High[i];
DownCandle[i] = MathMax(Open[i], Close[i]);
UpBar[i] = Low[i];
UpCandle[i] = MathMin(Open[i], Close[i]);
}
}
//+------------------------------------------------------------------+
//| 自定义指标初始化函数 |
//+------------------------------------------------------------------+
int init()
{
// 格式化到期时间显示
int yr = TimeYear(expiry_date);
int mn = TimeMonth(expiry_date);
int dy = TimeDay(expiry_date);
ExpiryInfo = StringConcatenate(yr, "年",
(mn < 10 ? "0" : ""), mn, "月",
(dy < 10 ? "0" : ""), dy, "日");
// 清除所有标签
ObjectsDeleteAll(0, OBJ_TEXT);
// 根据信号类型选择箭头代码
switch(信号类型)
{
case SIGNAL_CIRCLE: // 圆点
buy_arrow_code = 159;
sell_arrow_code = 159;
break;
case SIGNAL_ARROW_UPDOWN: // 空心上下箭头
buy_arrow_code = 241; // 空心上箭头
sell_arrow_code = 242; // 空心下箭头
break;
case SIGNAL_ARROW_FILLED: // 实心上下箭头
buy_arrow_code = 233; // 实心上箭头
sell_arrow_code = 234; // 实心下箭头
break;
case SIGNAL_ARROW_RIGHT: // 实心向右箭头
buy_arrow_code = 232; // 向右箭头(买入和卖出)
sell_arrow_code = 232; // 向右箭头(买入和卖出)
break;
case SIGNAL_THUMB: // 大拇指
buy_arrow_code = 67; // 大拇指向上
sell_arrow_code = 68; // 大拇指向下
break;
case SIGNAL_SUN: // 太阳
buy_arrow_code = 77; // 太阳符号
sell_arrow_code = 77; // 太阳符号
break;
default: // 默认使用圆点
buy_arrow_code = 159;
sell_arrow_code = 159;
break;
}
// 初始化指标缓冲区
IndicatorBuffers(11);
// 设置趋势线缓冲区
SetIndexBuffer(0, TrendUp);
SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 线条粗细, 上升颜色);
SetIndexLabel(0, "上升趋势");
SetIndexEmptyValue(0, EMPTY_VALUE);
SetIndexBuffer(1, TrendDown);
SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 线条粗细, 下降颜色);
SetIndexLabel(1, "下降趋势");
SetIndexEmptyValue(1, EMPTY_VALUE);
SetIndexBuffer(2, BuySignal);
SetIndexStyle(2, DRAW_ARROW, STYLE_SOLID, 信号大小, 买入颜色);
SetIndexArrow(2, buy_arrow_code);
SetIndexLabel(2, "买入信号");
SetIndexEmptyValue(2, EMPTY_VALUE);
SetIndexBuffer(3, SellSignal);
SetIndexStyle(3, DRAW_ARROW, STYLE_SOLID, 信号大小, 卖出颜色);
SetIndexArrow(3, sell_arrow_code);
SetIndexLabel(3, "卖出信号");
SetIndexEmptyValue(3, EMPTY_VALUE);
SetIndexBuffer(4, TrendUpDots);
SetIndexStyle(4, DRAW_ARROW, STYLE_SOLID, 点大小, 上升颜色);
SetIndexArrow(4, 159);
SetIndexLabel(4, "上升趋势点");
SetIndexEmptyValue(4, EMPTY_VALUE);
SetIndexBuffer(5, TrendDownDots);
SetIndexStyle(5, DRAW_ARROW, STYLE_SOLID, 点大小, 下降颜色);
SetIndexArrow(5, 159);
SetIndexLabel(5, "下降趋势点");
SetIndexEmptyValue(5, EMPTY_VALUE);
// 设置K线颜色缓冲区
SetIndexBuffer(6, UpBar);
SetIndexStyle(6, DRAW_HISTOGRAM, STYLE_SOLID, K线影线宽度, 上涨K线颜色);
SetIndexLabel(6, "上涨影线");
SetIndexEmptyValue(6, EMPTY_VALUE);
SetIndexBuffer(7, DownBar);
SetIndexStyle(7, DRAW_HISTOGRAM, STYLE_SOLID, K线影线宽度, 下跌K线颜色);
SetIndexLabel(7, "下跌影线");
SetIndexEmptyValue(7, EMPTY_VALUE);
SetIndexBuffer(8, UpCandle);
SetIndexStyle(8, DRAW_HISTOGRAM, STYLE_SOLID, K线实体宽度, 上涨K线颜色);
SetIndexLabel(8, "上涨实体");
SetIndexEmptyValue(8, EMPTY_VALUE);
SetIndexBuffer(9, DownCandle);
SetIndexStyle(9, DRAW_HISTOGRAM, STYLE_SOLID, K线实体宽度, 下跌K线颜色);
SetIndexLabel(9, "下跌实体");
SetIndexEmptyValue(9, EMPTY_VALUE);
// 趋势方向缓冲区
SetIndexBuffer(10, TrendBuffer);
SetIndexLabel(10, NULL);
// 初始化文字大小
g_text_size = (文字大小 <= 0) ? 8 : 文字大小;
return(0);
}
//+------------------------------------------------------------------+
//| 自定义指标迭代函数 |
//+------------------------------------------------------------------+
int start()
{
// 检查指标是否已过期
if(TimeCurrent() > expiry_date && !is_expired)
{
is_expired = true;
Alert("【指标策略已到期】\n请联系远山Ai量化团队\n微信:_yshan001");
return(0);
}
if(is_expired) return(0);
int counted_bars = IndicatorCounted();
int limit, i;
string objName;
datetime next_bar_time;
// 检查可能的错误
if(counted_bars < 0) return(-1);
// 最后计算的K线将被重新计算
if(counted_bars > 0) counted_bars--;
limit = Bars - counted_bars;
if(limit > Bars) limit = Bars;
// 初始化数组
ArrayInitialize(TrendUp, EMPTY_VALUE);
ArrayInitialize(TrendDown, EMPTY_VALUE);
ArrayInitialize(BuySignal, EMPTY_VALUE);
ArrayInitialize(SellSignal, EMPTY_VALUE);
ArrayInitialize(TrendUpDots, EMPTY_VALUE);
ArrayInitialize(TrendDownDots, EMPTY_VALUE);
double up[], down[], atr[], medianPrice[];
ArrayResize(up, Bars);
ArrayResize(down, Bars);
ArrayResize(atr, Bars);
ArrayResize(medianPrice, Bars);
// 首先计算所有K线的ATR和中值价格
for(i = 0; i < Bars; i++)
{
atr[i] = iATR(NULL, 0, ATR周期, i);
medianPrice[i] = (High[i] + Low[i]) / 2;
up[i] = medianPrice[i] + (乘数系数 * atr[i]);
down[i] = medianPrice[i] - (乘数系数 * atr[i]);
}
// 确定首个计算的K线的趋势方向
int firstBar = Bars - 1;
if(Close[firstBar] > up[firstBar])
TrendBuffer[firstBar] = 1; // 上升趋势
else if(Close[firstBar] < down[firstBar])
TrendBuffer[firstBar] = -1; // 下降趋势
else
TrendBuffer[firstBar] = 1; // 默认上升趋势
// 主计算循环
for(i = Bars - 2; i >= 0; i--)
{
// 趋势逻辑判断
if(Close[i] > up[i+1])
{
TrendBuffer[i] = 1; // 上升趋势
}
else if(Close[i] < down[i+1])
{
TrendBuffer[i] = -1; // 下降趋势
}
else
{
TrendBuffer[i] = TrendBuffer[i+1]; // 保持前一根K线的趋势
}
// 设置K线颜色
SetCandleColor(TrendBuffer[i] == 1, i);
// 更新上下轨
if(TrendBuffer[i] == 1) // 上升趋势
{
// 如果是上升趋势,保持上轨不变,调整下轨
if(down[i] < down[i+1])
down[i] = down[i+1];
// 根据趋势线样式绘制
if(趋势线样式 == STYLE_LINES || 趋势线样式 == STYLE_LINES_DOTS)
TrendUp[i] = down[i]; // 绘制线段
if(趋势线样式 == STYLE_LINES_DOTS || 趋势线样式 == STYLE_DOTS)
TrendUpDots[i] = down[i]; // 绘制圆点
// 趋势变化检测
if(TrendBuffer[i+1] == -1)
{
// 趋势从下降转为上升,添加买入信号
BuySignal[i] = down[i];
// 显示文字标签
if(显示文字)
{
objName = "Buy" + TimeToStr(Time[i]);
next_bar_time = i > 0 ? Time[i-1] : Time[i] + (Time[i] - Time[i+1]);
ObjectCreate(objName, OBJ_TEXT, 0, next_bar_time, down[i] - 文字偏移 * Point);
ObjectSetText(objName, 买入文字, g_text_size, "Arial", 买入颜色);
ObjectSet(objName, OBJPROP_ANCHOR, ANCHOR_TOP);
}
}
}
else // 下降趋势
{
// 如果是下降趋势,保持下轨不变,调整上轨
if(up[i] > up[i+1])
up[i] = up[i+1];
// 根据趋势线样式绘制
if(趋势线样式 == STYLE_LINES || 趋势线样式 == STYLE_LINES_DOTS)
TrendDown[i] = up[i]; // 绘制线段
if(趋势线样式 == STYLE_LINES_DOTS || 趋势线样式 == STYLE_DOTS)
TrendDownDots[i] = up[i]; // 绘制圆点
// 趋势变化检测
if(TrendBuffer[i+1] == 1)
{
// 趋势从上升转为下降,添加卖出信号
SellSignal[i] = up[i];
// 显示文字标签
if(显示文字)
{
objName = "Sell" + TimeToStr(Time[i]);
next_bar_time = i > 0 ? Time[i-1] : Time[i] + (Time[i] - Time[i+1]);
ObjectCreate(objName, OBJ_TEXT, 0, next_bar_time, up[i] + 文字偏移 * Point);
ObjectSetText(objName, 卖出文字, g_text_size, "Arial", 卖出颜色);
ObjectSet(objName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
//| 指标释放函数 |
//+------------------------------------------------------------------+
int deinit()
{
// 清除所有标签
ObjectsDeleteAll(0, OBJ_TEXT);
return(0);
}
//+------------------------------------------------------------------+
|