How to Play Custom Sound Files in MT5 Custom Indicator Like Default Price Alert?

 
Hello,

I'm developing a Bollinger Bands indicator with sound alerts, and I'm facing an issue with custom sound playback.

Issue:
1. In MT5's default price alerts (Tools > Options > Events), we can select and play ANY .wav file from the Sounds folder
2. However, in my custom indicator, I can only play default sounds, regardless of what I try

All attempts either fail with errors or only play the default sound
Cannot access the full list of available sounds like the default alert system

Cannot play custom sounds even when they exist in the Sounds folder

Questions:
Is it possible to play custom sounds in a custom indicator like the default price alert system?
If yes, how can we implement this functionality?
If no, is this a security limitation of MT5?
Any help or guidance would be greatly appreciated.

Thank you.
 
Your topic has been moved to the section: Technical Indicators
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
 
Gyuho Kim: Is it possible to play custom sounds in a custom indicator like the default price alert system?

Yes!

If you need help with your code, then please show your coding attempts. Use the CODE button (Alt-S) when inserting code.

Code button in editor

 
Fernando Carreiro #:

Yes!

If you need help with your code, then please show your coding attempts. Use the CODE button (Alt-S) when inserting code.

Hello?

First of all, thank you for answering my question.

I'm a beginner who doesn't know anything about coding. I recently grew up and started using the program to create the metrics I want, so I think the questions might be frustrating. Please understand.

First of all, I'll upload the code.


#property copyright "Copyright 2024"
#property link      ""
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots   3
#property strict

#property description "볼린저 밴드 알람 지표"

// 볼린저 밴드 기본 설정
input group "=== 볼린저 밴드 설정 ==="
input int    InpBandsPeriod = 20;         // 기간
input double InpBandsDeviations = 2.0;     // 표준편차
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE;  // 적용 가격

// 알람 설정
input group "=== 알람 설정 ==="
input bool   InpAlertEnabled = true;       // 알람 활성화
input bool   InpAlertUpperBand = true;     // 상단 밴드 알람
input bool   InpAlertMiddleBand = true;    // 중간 밴드 알람
input bool   InpAlertLowerBand = true;     // 하단 밴드 알람
input bool   InpShowPopup = true;          // 팝업 알람 표시
input bool   InpPlaySound = true;          // 소리 알람 재생

// 소리 알람 설정
input group "=== 소리 알람 설정 ==="
input string AlertSoundUpper = "alert_upper.wav"; // 상단 밴드 소리 파일 이름 (예: "alert_upper.wav")
input string AlertSoundMiddle = "alert_middle.wav"; // 중간 밴드 소리 파일 이름 (예: "alert_middle.wav")
input string AlertSoundLower = "alert_lower.wav"; // 하단 밴드 소리 파일 이름 (예: "alert_lower.wav")

// 알람 메시지 설정
input group "=== 알람 메시지 설정 ==="
input string InpMsgUpperBand = "가격이 상단 밴드에 도달했습니다!";    // 상단 밴드 메시지
input string InpMsgMiddleBand = "가격이 중간 밴드에 도달했습니다!";   // 중간 밴드 메시지
input string InpMsgLowerBand = "가격이 하단 밴드에 도달했습니다!";    // 하단 밴드 메시지

// 버퍼 선언
double UpperBuffer[];   // 상단 밴드 버퍼
double MiddleBuffer[];  // 중간 밴드 버퍼
double LowerBuffer[];   // 하단 밴드 버퍼

// 이전 알람 상태를 저장하기 위한 변수
bool wasAboveUpper = false; // 상단 밴드 알람 상태
bool wasBelowLower = false;  // 하단 밴드 알람 상태
bool wasAtMiddle = false;    // 중간 밴드 알람 상태

//+------------------------------------------------------------------+
//| 사용자 정의 지표 초기화 함수                                        |
//+------------------------------------------------------------------+
int OnInit()
{    
    // 상단 밴드 설정
    SetIndexBuffer(0, UpperBuffer, INDICATOR_DATA);
    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetInteger(0, PLOT_LINE_COLOR, clrRed);
    PlotIndexSetInteger(0, PLOT_LINE_WIDTH, 1);
    PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetString(0, PLOT_LABEL, "Upper Band");
    
    // 중간 밴드 설정
    SetIndexBuffer(1, MiddleBuffer, INDICATOR_DATA);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetInteger(1, PLOT_LINE_COLOR, clrBlue);
    PlotIndexSetInteger(1, PLOT_LINE_WIDTH, 1);
    PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetString(1, PLOT_LABEL, "Middle Band");
    
    // 하단 밴드 설정
    SetIndexBuffer(2, LowerBuffer, INDICATOR_DATA);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetInteger(2, PLOT_LINE_COLOR, clrRed);
    PlotIndexSetInteger(2, PLOT_LINE_WIDTH, 1);
    PlotIndexSetInteger(2, PLOT_DRAW_TYPE, DRAW_LINE);
    PlotIndexSetString(2, PLOT_LABEL, "Lower Band");
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 알람 전송 함수                                                      |
//+------------------------------------------------------------------+
void SendAlert(string message, string soundFile)
{
    string fullMessage = _Symbol + ": " + message;
    
    // 팝업 알람
    if(InpShowPopup)
        Alert(fullMessage);
        
    // 소리 알람
    if(InpPlaySound)
    {
        PlaySound(soundFile); // 사용자 지정 소리 파일 재생
    }
}

//+------------------------------------------------------------------+
//| 볼린저 밴드 계산 함수                                              |
//+------------------------------------------------------------------+
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(rates_total < InpBandsPeriod) return(0);
    
    int start;
    if(prev_calculated == 0)
        start = InpBandsPeriod;
    else
        start = prev_calculated - 1;
        
    // 볼린저 밴드 계산
    for(int i = start; i < rates_total; i++)
    {
        double sum = 0.0;
        double sum2 = 0.0;
        
        for(int j = 0; j < InpBandsPeriod; j++)
        {
            double price = close[i-j];
            sum += price;
            sum2 += MathPow(price, 2);
        }
        
        double middle = sum / InpBandsPeriod;
        double stddev = MathSqrt((sum2 - MathPow(sum, 2)/InpBandsPeriod) / InpBandsPeriod);
        
        MiddleBuffer[i] = middle;
        UpperBuffer[i] = middle + InpBandsDeviations * stddev;
        LowerBuffer[i] = middle - InpBandsDeviations * stddev;
        
        // 알람 체크 (마지막 봉에서만)
        if(InpAlertEnabled && i == rates_total-1)
        {
            // 상단 밴드 터치 알람
            if(InpAlertUpperBand && close[i] >= UpperBuffer[i] && !wasAboveUpper)
            {
                SendAlert(InpMsgUpperBand, AlertSoundUpper);
                wasAboveUpper = true;
            }
            else if(close[i] < UpperBuffer[i])
                wasAboveUpper = false;
                
            // 하단 밴드 터치 알람
            if(InpAlertLowerBand && close[i] <= LowerBuffer[i] && !wasBelowLower)
            {
                SendAlert(InpMsgLowerBand, AlertSoundLower);
                wasBelowLower = true;
            }
            else if(close[i] > LowerBuffer[i])
                wasBelowLower = false;
                
            // 중간 밴드 터치 알람
            if(InpAlertMiddleBand && 
               MathAbs(close[i] - MiddleBuffer[i]) <= 0.0001 && 
               !wasAtMiddle)
            {
                SendAlert(InpMsgMiddleBand, AlertSoundMiddle);
                wasAtMiddle = true;
            }
            else if(MathAbs(close[i] - MiddleBuffer[i]) > 0.0001)
                wasAtMiddle = false;
        }
    }
    
    return(rates_total);
}

The key is that you want to specify the sound you want in the indicator settings. Referring to the link you posted, I asked the cursor to play only the default sound (alert.wav).

The sound setting designation specifies the sound in the C:\Program Files\Infinox MetaTrader 5 Terminal\Sounds folder, and even if you specify "a.wav" or "a", only the default sound is played.

I don't know if the code is wrong or if I'm wrong in the indicator setting.

I'd appreciate it if you could take a look and let me know what's wrong.


I have one more question.

Like setting line color in indicator setting, and like the default alarm setting method, is sound specification impossible in indicator setting?

Once again, thank you for your interest in my question, I look forward to hearing from you.


 
Gyuho Kim #:

Like setting line color in indicator setting, and like the default alarm setting method, is sound specification impossible in indicator setting?

no it's not impossible, but when you use these functions like Alert and PlaySound, they will keep playing the alert until they are commanded to stop

this is one of my oldest indicator codes which uses a custom alert

Code Base

Moving Average with alerts on price crossovers

Conor Mcnamara, 2023.07.30 15:19

I wanted to build a moving average which would create an alert when the price moves over the line by a user defined amount of points. It creates both bullish and bearish signals depending on the direction of market price moving through the MA. It is designed for slow length moving averages (default is 200-day MA). EDIT: I now added a second version of the indicator which uses Arrow buffers instead of ObjectCreate.

I wrote, as you can see: audio sample must be placed in data_folder/MQL5/Files 

If the custom alert sound isn't placed there, it will not work

this is another way of applying the function using #resource property and it's better as it makes it portable:

Code Base

Connect Disconnect Sound Alert

Rajesh Kumar Nait, 2024.01.07 21:36

This utility is simple example to add sound alert on connect / disconnect