English Русский Español Deutsch 日本語
preview
开发自定义市场情绪指标

开发自定义市场情绪指标

MetaTrader 5 — 示例 |
35 0
Hlomohang John Borotho
Hlomohang John Borotho

引言

识别市场的真实方向颇具挑战,尤其是当不同时间框架给出相互矛盾的信息时。交易者可能会在 30 分钟图表上看到强劲的看涨走势,而 4 小时图表仍显示看跌压力。这常常导致困惑、交易方向错位,或逆着主流市场偏向建仓。如果没有一种结构化的方法来对齐较高与较低时间框架的信号,交易者就可能基于不完整信息做出冲动决策,最终降低交易的一致性与盈利能力。

Market Sentiment 自定义指标通过把多个时间框架的信号汇总到一个易于阅读的单一面板中,来解决这一问题。通过把较高时间框架的趋势与较低时间框架的结构结合起来进行分析,它把市场归类为五种清晰的情绪状态:看涨、看跌、风险偏好、风险规避或中性。这种分层方法帮助交易者与大局保持一致,同时借助短期确认来把握进场时机。因此,它简化了决策过程、减少了不确定性,并改善了交易与当前市场状况的契合度。



开发与逻辑

看涨情绪:

当交易者和投资者普遍预期价格上涨时出现。其特征是买盘压力强于卖盘压力。常见信号包括价格行为中更高的高点与更高的低点、上涨过程中的强劲成交量,以及积极的经济或新闻前景。在极端情况下,看涨情绪可能导致亢奋,乐观情绪变得过度,这往往出现在牛市行情的末期。

看跌情绪:

反映对价格将下跌的预期,卖盘压力大于买盘压力。通常通过价格行为中更低的高点与更低的低点、下跌过程中的强劲成交量,以及负面的经济或新闻进展来识别。在极端情况下,看跌情绪可能表现为恐慌,引发激进的抛售,这往往发生在市场底部或附近。

中性情绪:

当市场参与者犹豫不决或认为买卖双方势均力敌时出现。在这种环境中,价格通常在区间内波动,未形成明确的上升趋势或下降趋势。关键信号包括盘整阶段、低波动性,以及交易者在建立头寸前等待确认。

风险偏好情绪:

描述一种投资者更愿意承担风险的市场情绪,资金往往流入股票、大宗商品和高收益资产。资本流入具有更高回报潜力的工具。典型信号包括股指上涨,以及对黄金或政府债券等避险资产的需求疲软。

风险规避情绪:

另一方面,当投资者因恐惧或不确定性而寻求安全时,就会出现这种情绪。在这种情况下,资本转向传统上更安全的资产,如黄金、美元、瑞士法郎或政府债券。其典型特征是股指下跌,以及对避险货币和避险资产的需求上升。

时间框架关系:

架构图:



让我们开始

//+------------------------------------------------------------------+
//|                                                  Market_Sent.mq5 |
//|                        GIT under Copyright 2025, MetaQuotes Ltd. |
//|                     https://www.mql5.com/en/users/johnhlomohang/ |
//+------------------------------------------------------------------+
#property copyright "GIT under Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com/en/users/johnhlomohang/"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0


//+------------------------------------------------------------------+
//| Input parameters                                                 |
//+------------------------------------------------------------------+
input group "Timeframe Settings"
input ENUM_TIMEFRAMES HigherTF = PERIOD_H4;     
input ENUM_TIMEFRAMES LowerTF1 = PERIOD_H1;     
input ENUM_TIMEFRAMES LowerTF2 = PERIOD_M30;    

input group "Indicator Settings"
input int MAPeriod = 200;                       
input int SwingLookback = 5;                    
input double ATRThreshold = 0.002;              

input group "Visual Settings"
// force top-left dark theme
input int PanelCorner = 0;                      
input int PanelX = 10;                          
input int PanelY = 10;                          
input string FontFace = "Arial";                
input int FontSize = 10;                        
input color BullishColor = clrLimeGreen;        
input color BearishColor = clrRed;              
input color RiskOnColor = clrDodgerBlue;        
input color RiskOffColor = clrOrangeRed;        
input color NeutralColor = clrGold;      

我们首先搭建 MQL5 中自定义市场情绪指标的框架。顶部区段包含版权、版本和链接等元数据,以及定义指标属性的指令。indicator_buffers 0 与 indicator_plots 0 意味着不使用标准缓冲区或绘图,因为该指标更像是一种面板式的可视化工具,而非绘制线条或柱状图。这些初始设置实质上确立了自定义情绪分析逻辑运行的环境。

输入参数为交易者配置指标提供了灵活性。"Timeframe Settings"(时间框架设置)组允许用户选择用于情绪分析的较高时间框架(默认 H4)和两个较低时间框架(H1 和 M30)。在 "Indicator Settings"(指标设置)下,交易者可以调整移动平均周期、波段回看范围和 ATR 阈值等技术参数,这些参数用于解读价格行为与波动性。最后,"Visual Settings"(视觉设置)组控制情绪面板在图表上的显示方式,包括其位置、字体样式、字号,以及用于表示看涨、看跌、风险偏好、风险规避和中性状况的具体颜色。这些输入共同构成了一个灵活的基础,用于跨多个时间框架检测并可视化市场情绪。

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
int higherTFHandle, lowerTF1Handle, lowerTF2Handle;
double higherTFMA[], lowerTF1MA[], lowerTF2MA[];
datetime lastUpdateTime = 0;
string indicatorName = "MarketSentiment";

//--- helper: convert timeframe to string
string TFtoString(int tf)
{
   switch(tf)
   {
      case PERIOD_M1:  return "M1";
      case PERIOD_M5:  return "M5";
      case PERIOD_M15: return "M15";
      case PERIOD_M30: return "M30";
      case PERIOD_H1:  return "H1";
      case PERIOD_H4:  return "H4";
      case PERIOD_D1:  return "D1";
      case PERIOD_W1:  return "W1";
      case PERIOD_MN1: return "MN";
      default: return "TF?";
   }
}

本区段定义了市场情绪指标所需的全局变量和辅助函数。三个句柄变量(higherTFHandle、lowerTF1Handle 和 lowerTF2Handle)用于存储对不同时间框架上移动平均计算的引用,而数组(higherTFMA[]、lowerTF1MA[]、lowerTF2MA[])则保存其对应的数据值。lastUpdateTime 变量被初始化,用于跟踪指标上次刷新的时间,确保高效更新;indicatorName 则为绘制在图表上的对象提供一个一致的标签。此外,TFtoString() 辅助函数将数字形式的时间框架常量转换为可读的字符串(例如 PERIOD_H1 -> "H1"),这对于在指标面板中标记或显示信息很有用。

//+------------------------------------------------------------------+
//| OnInit                                                           |
//+------------------------------------------------------------------+
int OnInit()
{
    indicatorName = "MarketSentiment_" + IntegerToString(ChartID());
    
    higherTFHandle = iMA(_Symbol, HigherTF, MAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    lowerTF1Handle = iMA(_Symbol, LowerTF1, MAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    lowerTF2Handle = iMA(_Symbol, LowerTF2, MAPeriod, 0, MODE_EMA, PRICE_CLOSE);
    
    ArraySetAsSeries(higherTFMA, true);
    ArraySetAsSeries(lowerTF1MA, true);
    ArraySetAsSeries(lowerTF2MA, true);
    
    CreatePanel();
    return(INIT_SUCCEEDED);
}

OnInit() 函数通过以下方式初始化市场情绪指标:使用图表 ID 为图表对象设置唯一命名,并针对较高和较低时间框架,以指定的周期和 EMA 方法创建移动平均句柄。它还将 MA 数组配置为时间序列方向,确保在访问最近数值时索引更加简便。最后,它调用 CreatePanel() 函数在图表上绘制情绪显示面板,然后返回 INIT_SUCCEEDED 以确认初始化成功。

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    ObjectsDeleteAll(0, indicatorName);
    IndicatorRelease(higherTFHandle);
    IndicatorRelease(lowerTF1Handle);
    IndicatorRelease(lowerTF2Handle);
}

OnDeinit() 函数确保在移除指标时进行适当的清理:删除与其唯一 indicatorName 关联的所有图表对象,并释放较高和较低时间框架移动平均的句柄,从而防止内存泄漏并保持图表环境整洁。

//+------------------------------------------------------------------+
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 (TimeCurrent() - lastUpdateTime < 10 && prev_calculated > 0)
        return(rates_total);
    
    lastUpdateTime = TimeCurrent();
    
    CopyBuffer(higherTFHandle, 0, 0, 3, higherTFMA);
    CopyBuffer(lowerTF1Handle, 0, 0, 3, lowerTF1MA);
    CopyBuffer(lowerTF2Handle, 0, 0, 3, lowerTF2MA);
    
    double higherTFPrice = iClose(_Symbol, HigherTF, 0);
    double lowerTF1Price = iClose(_Symbol, LowerTF1, 0);
    double lowerTF2Price = iClose(_Symbol, LowerTF2, 0);
    
    int higherTFBias = GetHigherTFBias(higherTFPrice, higherTFMA[0]);
    
    bool lowerTF1Bullish = IsBullishStructure(LowerTF1, SwingLookback);
    bool lowerTF1Bearish = IsBearishStructure(LowerTF1, SwingLookback);
    bool lowerTF2Bullish = IsBullishStructure(LowerTF2, SwingLookback);
    bool lowerTF2Bearish = IsBearishStructure(LowerTF2, SwingLookback);
    
    bool lowerTF1Breakout = HasBreakout(LowerTF1, SwingLookback, higherTFBias);
    bool lowerTF2Breakout = HasBreakout(LowerTF2, SwingLookback, higherTFBias);
    
    int sentiment = DetermineSentiment(
        higherTFBias, 
        lowerTF1Bullish, lowerTF1Bearish, lowerTF1Breakout,
        lowerTF2Bullish, lowerTF2Bearish, lowerTF2Breakout
    );
    
    UpdatePanel(higherTFBias,
                lowerTF1Bullish, lowerTF1Bearish,
                lowerTF2Bullish, lowerTF2Bearish,
                sentiment);
    
    return(rates_total);
}

OnCalculate() 函数充当指标的主处理循环,每次有新的价格数据或报价(tick)到达时运行。它首先设置一个更新节流机制,确保仅在距离上次更新至少过去 10 秒时才进行计算,从而提高效率。随后,该函数从较高和较低时间框架的缓冲区中复制移动平均值,并获取每个时间框架的最新收盘价,这些数据构成情绪评估的基础。

在收集价格和 MA 数据之后,该函数判定较高时间框架的方向倾向,并检查较低时间框架上的结构条件(看涨或看跌形态)。它还验证与较高时间框架偏向一致的潜在突破。这些条件在 DetermineSentiment() 函数中综合起来,将市场分类为看涨、看跌、风险偏好、风险规避或中性状态。最后,结果通过 UpdatePanel() 在图表上直观呈现,为交易者提供一个跨多个时间框架的实时情绪仪表盘。

//+------------------------------------------------------------------+
//| Determine higher timeframe bias                                  |
//+------------------------------------------------------------------+
int GetHigherTFBias(double price, double maValue)
{
    double deviation = MathAbs(price - maValue) / maValue;
    if (price > maValue && deviation > ATRThreshold) return 1;
    else if (price < maValue && deviation > ATRThreshold) return -1;
    else return 0;
}

该函数通过将当前价格与其移动平均值进行比较,来评估较高时间框架的趋势方向。如果价格高于 MA 且偏离度超过定义的 ATR 阈值,则返回 1(看涨偏向);如果价格低于 MA 且偏离足够大,则返回 -1(看跌偏向)。如果两个条件都不满足,则返回 0,表示较高时间框架偏向中性或不明朗。

//+------------------------------------------------------------------+
//| Bullish structure                                                |
//+------------------------------------------------------------------+
bool IsBullishStructure(ENUM_TIMEFRAMES tf, int lookback)
{
    int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback * 2, 1);
    int swingLowIndex  = iLowest (_Symbol, tf, MODE_LOW,  lookback * 2, 1);
    int prevHigh = iHighest(_Symbol, tf, MODE_HIGH, lookback, lookback+1);
    int prevLow  = iLowest (_Symbol, tf, MODE_LOW,  lookback, lookback+1);
    if (swingHighIndex==-1 || swingLowIndex==-1 || prevHigh==-1 || prevLow==-1) return false;
    return (iHigh(_Symbol, tf, swingHighIndex) > iHigh(_Symbol, tf, prevHigh) &&
            iLow(_Symbol, tf, swingLowIndex)   > iLow (_Symbol, tf, prevLow));
}
//+------------------------------------------------------------------+
//| Bearish structure                                                |
//+------------------------------------------------------------------+
bool IsBearishStructure(ENUM_TIMEFRAMES tf, int lookback)
{
    int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback * 2, 1);
    int swingLowIndex  = iLowest (_Symbol, tf, MODE_LOW,  lookback * 2, 1);
    int prevHigh = iHighest(_Symbol, tf, MODE_HIGH, lookback, lookback+1);
    int prevLow  = iLowest (_Symbol, tf, MODE_LOW,  lookback, lookback+1);
    if (swingHighIndex==-1 || swingLowIndex==-1 || prevHigh==-1 || prevLow==-1) return false;
    return (iHigh(_Symbol, tf, swingHighIndex) < iHigh(_Symbol, tf, prevHigh) &&
            iLow(_Symbol, tf, swingLowIndex)   < iLow (_Symbol, tf, prevLow));
}

IsBullishStructure () 函数通过将最新的波段高点和低点与之前的波段高低点进行比较,在给定的时间框架上识别看涨价格形态。它首先使用 iHighest 和 iLowest 函数定位当前和之前的波段高点和低点。如果当前高点高于前高点且当前低点高于前低点,该函数返回 true,表示看涨结构;否则返回 false。

同样,IsBearishStructure () 函数通过将最近的波段高低点与之前的进行比较来检测看跌形态。如果当前高点低于前高点且当前低点低于前低点,则返回 true,表示看跌结构。这两个函数都依赖指定回看周期内的波段分析,为指标提供了一种相对于前一段走势来评估短期价格趋势的方法。

//+------------------------------------------------------------------+
bool HasBreakout(ENUM_TIMEFRAMES tf, int lookback, int higherTFBias)
{
    int swingHighIndex = iHighest(_Symbol, tf, MODE_HIGH, lookback, 1);
    int swingLowIndex  = iLowest (_Symbol, tf, MODE_LOW,  lookback, 1);
    if (swingHighIndex==-1 || swingLowIndex==-1) return false;
    double swingHigh = iHigh(_Symbol, tf, swingHighIndex);
    double swingLow  = iLow (_Symbol, tf, swingLowIndex);
    double price = iClose(_Symbol, tf, 0);
    if (higherTFBias==1) return (price > swingHigh);
    if (higherTFBias==-1) return (price < swingLow);
    return false;
}

该函数结合较高时间框架的方向,检查当前价格是否在指定时间框架上向上突破近期波段高点或向下跌破近期波段低点。它识别最近的波段高点和低点,如果其中任一不可用,则返回 false。在较高时间框架为看涨偏向时,若当前价格超过波段高点则返回 true;在看跌偏向时,若价格跌破波段低点则返回 true。如果较高时间框架偏向为中性,则不认为存在突破,函数返回 false。

//+------------------------------------------------------------------+
int DetermineSentiment(int higherTFBias, 
                      bool tf1Bullish, bool tf1Bearish, bool tf1Breakout,
                      bool tf2Bullish, bool tf2Bearish, bool tf2Breakout)
{
    if (higherTFBias==1 && tf1Bullish && tf2Bullish) return 1;
    if (higherTFBias==-1 && tf1Bearish && tf2Bearish) return -1;
    if (higherTFBias==1 && (tf1Breakout||tf2Breakout)) return 2;
    if (higherTFBias==-1 && (tf1Breakout||tf2Breakout)) return -2;
    return 0;
}

DetermineSentiment() 函数综合多个时间框架的市场状况,对整体市场情绪进行分类。如果较高时间框架为看涨且两个较低时间框架均显示看涨结构,则返回 1(看涨情绪);在相反条件下返回 -1(看跌情绪);若较高时间框架偏向看涨,且任一较低时间框架出现向上突破,则返回 2(风险偏好);若较高时间框架偏向看跌,且任一较低时间框架出现向下突破,则返回 -2(风险规避)。。如果这些条件均不满足,则返回 0,表示中性或震荡的市场状态。

//+------------------------------------------------------------------+
//| Panel Creation (dark theme, top-left)                            |
//+------------------------------------------------------------------+
void CreatePanel()
{
   string bg = indicatorName + "_BG";
   ObjectCreate(0, bg, OBJ_RECTANGLE_LABEL, 0, 0, 0);
   ObjectSetInteger(0, bg, OBJPROP_XDISTANCE, PanelX);
   ObjectSetInteger(0, bg, OBJPROP_YDISTANCE, PanelY);
   ObjectSetInteger(0, bg, OBJPROP_XSIZE, 200);
   ObjectSetInteger(0, bg, OBJPROP_YSIZE, 120);
   ObjectSetInteger(0, bg, OBJPROP_CORNER, 0);
   ObjectSetInteger(0, bg, OBJPROP_BGCOLOR, clrBlack);
   ObjectSetInteger(0, bg, OBJPROP_BORDER_COLOR, clrGray);
   ObjectSetInteger(0, bg, OBJPROP_BACK, true);
   ObjectSetInteger(0, bg, OBJPROP_SELECTABLE, false);
   ObjectSetInteger(0, bg, OBJPROP_HIDDEN, true);

   string title = indicatorName + "_Title";
   ObjectCreate(0, title, OBJ_LABEL, 0, 0, 0);
   ObjectSetInteger(0, title, OBJPROP_XDISTANCE, PanelX+10);
   ObjectSetInteger(0, title, OBJPROP_YDISTANCE, PanelY+10);
   ObjectSetInteger(0, title, OBJPROP_CORNER, 0);
   ObjectSetString (0, title, OBJPROP_TEXT, "Market Sentiment");
   ObjectSetInteger(0, title, OBJPROP_COLOR, clrWhite);
   ObjectSetString (0, title, OBJPROP_FONT, FontFace);
   ObjectSetInteger(0, title, OBJPROP_FONTSIZE, FontSize);

   string tfs[3] = { TFtoString(HigherTF), TFtoString(LowerTF1), TFtoString(LowerTF2) };
   for(int i=0;i<3;i++)
   {
      string tfLabel = indicatorName+"_TF"+(string)i;
      ObjectCreate(0, tfLabel, OBJ_LABEL, 0,0,0);
      ObjectSetInteger(0, tfLabel, OBJPROP_XDISTANCE, PanelX+10);
      ObjectSetInteger(0, tfLabel, OBJPROP_YDISTANCE, PanelY+30+i*20);
      ObjectSetInteger(0, tfLabel, OBJPROP_CORNER, 0);
      ObjectSetString (0, tfLabel, OBJPROP_TEXT, tfs[i]+":");
      ObjectSetInteger(0, tfLabel, OBJPROP_COLOR, clrLightGray);
      ObjectSetString (0, tfLabel, OBJPROP_FONT, FontFace);
      ObjectSetInteger(0, tfLabel, OBJPROP_FONTSIZE, FontSize);

      string sentLabel = indicatorName+"_Sentiment"+(string)i;
      ObjectCreate(0, sentLabel, OBJ_LABEL, 0,0,0);
      ObjectSetInteger(0, sentLabel, OBJPROP_XDISTANCE, PanelX+100);
      ObjectSetInteger(0, sentLabel, OBJPROP_YDISTANCE, PanelY+30+i*20);
      ObjectSetInteger(0, sentLabel, OBJPROP_CORNER, 0);
      ObjectSetString (0, sentLabel, OBJPROP_TEXT, "N/A");
      ObjectSetInteger(0, sentLabel, OBJPROP_COLOR, NeutralColor);
      ObjectSetString (0, sentLabel, OBJPROP_FONT, FontFace);
      ObjectSetInteger(0, sentLabel, OBJPROP_FONTSIZE, FontSize);
   }

   string fnl = indicatorName+"_Final";
   ObjectCreate(0, fnl, OBJ_LABEL, 0,0,0);
   ObjectSetInteger(0, fnl, OBJPROP_XDISTANCE, PanelX+10);
   ObjectSetInteger(0, fnl, OBJPROP_YDISTANCE, PanelY+100);
   ObjectSetInteger(0, fnl, OBJPROP_CORNER, 0);
   ObjectSetString (0, fnl, OBJPROP_TEXT, "Final: Neutral");
   ObjectSetInteger(0, fnl, OBJPROP_COLOR, NeutralColor);
   ObjectSetString (0, fnl, OBJPROP_FONT, FontFace);
   ObjectSetInteger(0, fnl, OBJPROP_FONTSIZE, FontSize+2);
}

CreatePanel () 函数在图表左上角初始化一个视觉上井然有序的面板,采用适合白色背景、黑色图表元素的深色主题。它首先创建一个黑色填充、灰色边框的背景矩形,确保其位于其他图表对象之后且不可选择。随后在面板顶部添加一个标题标签,清晰地标明这是 "Market Sentiment" 指标,使用白色文字以便在深色背景上清晰可见。

在标题下方,该函数为所监控的三个时间框架(较高与较低时间框架)分别生成标签,显示其名称以及初始化为 "N/A" 的中性颜色占位情绪值。最后,底部一个更大的标签用于汇总最终的市场情绪,初始设置为 "Neutral"。这一设置便于在单个紧凑面板中轻松地跨多个时间框架可视化跟踪市场偏向。

//+------------------------------------------------------------------+
//| Panel Update                                                     |
//+------------------------------------------------------------------+
void UpdatePanel(int higherTFBias,
                 bool tf1Bullish, bool tf1Bearish,
                 bool tf2Bullish, bool tf2Bearish,
                 int sentiment)
{
    // Higher TF
    string txt="Neutral"; color col=NeutralColor;
    if(higherTFBias==1){txt="Bullish"; col=BullishColor;}
    else if(higherTFBias==-1){txt="Bearish"; col=BearishColor;}
    ObjectSetString(0, indicatorName+"_Sentiment0", OBJPROP_TEXT, txt);
    ObjectSetInteger(0, indicatorName+"_Sentiment0", OBJPROP_COLOR, col);

    // Lower TF1
    txt="Neutral"; col=NeutralColor;
    if(tf1Bullish){txt="Bullish"; col=BullishColor;}
    else if(tf1Bearish){txt="Bearish"; col=BearishColor;}
    ObjectSetString(0, indicatorName+"_Sentiment1", OBJPROP_TEXT, txt);
    ObjectSetInteger(0, indicatorName+"_Sentiment1", OBJPROP_COLOR, col);

    // Lower TF2
    txt="Neutral"; col=NeutralColor;
    if(tf2Bullish){txt="Bullish"; col=BullishColor;}
    else if(tf2Bearish){txt="Bearish"; col=BearishColor;}
    ObjectSetString(0, indicatorName+"_Sentiment2", OBJPROP_TEXT, txt);
    ObjectSetInteger(0, indicatorName+"_Sentiment2", OBJPROP_COLOR, col);

    // Final
    string finalSent="Neutral"; color finalCol=NeutralColor;
    switch(sentiment){
        case 1: finalSent="Bullish"; finalCol=BullishColor; break;
        case -1: finalSent="Bearish"; finalCol=BearishColor; break;
        case 2: finalSent="Risk-On"; finalCol=RiskOnColor; break;
        case -2: finalSent="Risk-Off"; finalCol=RiskOffColor; break;
    }
    ObjectSetString(0, indicatorName+"_Final", OBJPROP_TEXT, "Final: "+finalSent);
    ObjectSetInteger(0, indicatorName+"_Final", OBJPROP_COLOR, finalCol);
}

UpdatePanel () 函数根据最新分析动态刷新市场情绪面板。它首先评估较高时间框架的偏向,将其对应的标签更新为 "Bullish"(看涨)、"Bearish"(看跌)或 "Neutral"(中性),并赋予相应的颜色。然后,它对两个较低时间框架执行相同操作,检查其看涨或看跌结构,并将结果以正确的颜色编码反映在各自的标签中。

最后,该函数通过评估所有时间框架的偏向和突破的组合,确定整体市场情绪。最终情绪标签被更新为显示 "Bullish"(看涨)、"Bearish"(看跌)、"Risk-On"(风险偏好)、"Risk-Off"(风险规避)或 "Neutral"(中性),并使用相应颜色,以快速、直观地总结当前市场状况。这确保交易者能够一眼即时判断多个时间框架下的市场方向。



结论

总之,我们开发了一个整合多个时间框架的自定义市场情绪指标,以清晰、可视化的方式呈现市场状况。该指标在较高和较低时间框架上计算移动平均值,利用波段高点和低点识别看涨或看跌结构,检测潜在突破,并确定整体情绪。位于左上角的深色主题面板显示每个时间框架的情绪以及综合的最终情绪,并通过颜色编码快速区分看涨、看跌、风险偏好、风险规避和中性状况。

总而言之,该指标通过将复杂的市场数据整合为易于阅读的可视化格式,帮助交易者做出更明智的决策。通过实时提供多时间框架的情绪分析,它使交易者能够快速评估市场趋势、识别潜在交易机会,并使自己的策略与当前市场状况保持一致,从而减少不确定性并提高决策效率。

本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/19422

附加的文件 |
Market_Sent.mq5 (13.68 KB)
交易策略 交易策略
各种交易策略的分类都是任意的,下面这种分类强调从交易的基本概念上分类。
基于N-BEATS网络的外汇EA 基于N-BEATS网络的外汇EA
在MetaTrader 5中实现面向外汇交易的N-BEATS架构,支持分位数预测与自适应风险管理。本架构通过双线性归一化、适配金融数据的专用损失函数完成改造。基于2025年数据的回测结果显示模型无法产生盈利,印证了理论成果与实际交易表现之间存在差距。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
基于PatchTST的神经网络交易EA 基于PatchTST的神经网络交易EA
本文介绍了PatchTST这一革新性架构,它是专为金融时序分析定制的Transformer模型,将市场数据切分为16根K线的补丁块,以此实现高效运算。我们将讲解基于MQL5的交易机器人完整实现方案,涵盖从数学原理、数据结构,到自带风控与持续学习系统的成品EA。