//+------------------------------------------------------------------+
//| MoneyFlowMonitor.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrRed
#property indicator_color3 clrGreen
#property indicator_color4 clrGray
#property indicator_width1 2
#property indicator_width2 2
#property indicator_width3 1
//--- 输入参数
input int MFI_Period = 14; // MFI周期
input double Volume_Threshold = 1.2; // 成交量阈值
input bool Show_Arrows = true; // 显示箭头信号
//--- 缓冲区
double MoneyFlowBuffer[];
double BullishFlowBuffer[];
double BearishFlowBuffer[];
double SignalLineBuffer[];
//+------------------------------------------------------------------+
//| 自定义初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
// 设置指标缓冲区
SetIndexBuffer(0, MoneyFlowBuffer);
SetIndexStyle(0, DRAW_LINE);
SetIndexLabel(0, "Money Flow");
SetIndexBuffer(1, BullishFlowBuffer);
SetIndexStyle(1, DRAW_HISTOGRAM);
SetIndexLabel(1, "Bullish Flow");
SetIndexBuffer(2, BearishFlowBuffer);
SetIndexStyle(2, DRAW_HISTOGRAM);
SetIndexLabel(2, "Bearish Flow");
SetIndexBuffer(3, SignalLineBuffer);
SetIndexStyle(3, DRAW_LINE);
SetIndexLabel(3, "Signal Line");
// 初始化缓冲区值为EMPTY_VALUE
ArrayInitialize(MoneyFlowBuffer, EMPTY_VALUE);
ArrayInitialize(BullishFlowBuffer, EMPTY_VALUE);
ArrayInitialize(BearishFlowBuffer, EMPTY_VALUE);
ArrayInitialize(SignalLineBuffer, EMPTY_VALUE);
IndicatorShortName("MoneyFlow Monitor(" + string(MFI_Period) + ")");
// 创建趋势信号标签
ObjectCreate(0, "TrendSignal", OBJ_LABEL, 0, 0, 0);
ObjectSetString(0, "TrendSignal", OBJPROP_TEXT, "Money Flow: Initializing...");
ObjectSetInteger(0, "TrendSignal", OBJPROP_CORNER, CORNER_LEFT_UPPER);
ObjectSetInteger(0, "TrendSignal", OBJPROP_XDISTANCE, 10);
ObjectSetInteger(0, "TrendSignal", OBJPROP_YDISTANCE, 30);
ObjectSetInteger(0, "TrendSignal", OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, "TrendSignal", OBJPROP_BGCOLOR, clrBlack);
ObjectSetInteger(0, "TrendSignal", OBJPROP_FONTSIZE, 10);
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
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
if(rates_total <= MFI_Period)
return(0);
int limit = rates_total - prev_calculated;
if(prev_calculated > 0)
limit++;
for(int i = limit-1; i >= 0; i--) // 在循环内部声明变量
{
// 计算典型价格
double typical_price = (high + low + close) / 3;
double money_ratio = 0;
double money_flow = 0;
// 计算资金流比率
if(i < rates_total-1 && tick_volume[i+1] > 0)
{
double typical_price_prev = (high[i+1] + low[i+1] + close[i+1]) / 3;
double volume_factor = (double)tick_volume / (double)tick_volume[i+1];
if(volume_factor > Volume_Threshold)
volume_factor = Volume_Threshold;
money_ratio = (typical_price - typical_price_prev) / typical_price_prev * volume_factor;
}
else
{
money_ratio = 0;
}
// 计算资金流
money_flow = money_ratio * tick_volume;
MoneyFlowBuffer = money_flow;
// 分离看涨和看跌资金流
if(money_flow > 0)
{
BullishFlowBuffer = money_flow;
BearishFlowBuffer = 0;
}
else
{
BullishFlowBuffer = 0;
BearishFlowBuffer = MathAbs(money_flow);
}
// 计算信号线 (3期移动平均)
if(i <= rates_total-3)
{
SignalLineBuffer = (MoneyFlowBuffer + MoneyFlowBuffer[i+1] + MoneyFlowBuffer[i+2]) / 3;
}
else
{
SignalLineBuffer = MoneyFlowBuffer;
}
}
// 更新趋势信号
ObjectSetString(0, "TrendSignal", OBJPROP_TEXT, "Money Flow: " + GetTrendSignal());
return(rates_total);
}
//+------------------------------------------------------------------+
//| 趋势判断函数 |
//+------------------------------------------------------------------+
string GetTrendSignal()
{
int current = 0;
// 检查缓冲区是否有足够数据
if(ArraySize(MoneyFlowBuffer) < 2 || ArraySize(SignalLineBuffer) < 1)
return "⚪ INSUFFICIENT DATA";
double currentMF = MoneyFlowBuffer[current];
double signalMF = SignalLineBuffer[current];
double prevMF = (ArraySize(MoneyFlowBuffer) > 1) ? MoneyFlowBuffer[current+1] : 0;
// 检查数据有效性
if(currentMF == EMPTY_VALUE || signalMF == EMPTY_VALUE)
return "⚪ NO DATA";
string signal = "";
// 趋势判断逻辑
if(currentMF > signalMF && currentMF > prevMF)
{
signal = "🟢 STRONG BULLISH";
}
else if(currentMF > signalMF && currentMF <= prevMF)
{
signal = "🔵 MILD BULLISH";
}
else if(currentMF < signalMF && currentMF < prevMF)
{
signal = "🔴 STRONG BEARISH";
}
else if(currentMF < signalMF && currentMF >= prevMF)
{
signal = "🟠 MILD BEARISH";
}
else
{
signal = "⚪ NEUTRAL";
}
return signal;
}
//+------------------------------------------------------------------+
//| 在图表上显示趋势信息 |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id == CHARTEVENT_CHART_CHANGE)
{
ObjectSetString(0, "TrendSignal", OBJPROP_TEXT, "Money Flow: " + GetTrendSignal());
}
}
//+------------------------------------------------------------------+
//| 去初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 删除创建的对象
ObjectDelete(0, "TrendSignal");
} |