This is also pseudocode. I haven't tested it
#define _undefinedLastAlertTime 0 datetime last_alert_time = _undefinedLastAlertTime; void someFunction(const datetime &time[]) { if(time[0] != last_alert_time) { if(last_alert_time != _undefinedLastAlertTime) Alert("Buy Signal Detected"); last_alert_time = time[0]; } }
but I do not want this because the indicator will not alert new signal if it repaints.
I don't understand why you store and check the bar time if you want to send notifications about signal changes on the same bar.
I don't understand why you store and check the bar time if you want to send notifications about signal changes on the same bar.
Hello thanks for replying. At first, I tried not check the bar time but the alert will comes up many times. When I use my pseudocode above, the alert will triggered once at current bar and when it repaint the new alert triggered at new bar
Your problem statement is a bit strange. I'm not sure I understood correctly what you want to do.
My example works according to the following logic:
- Notify about buy signal if the previous notification was about sell signal;
- Notify about sell signal if the previous notification was about buy signal;
- If at the moment of attaching the indicator there was already a signal - ignore it (the next notification only when the opposite signal appears)
Signal generation logic:
- buy - current candle is bullish and candle body is not less than 10 points
- sell - current candle is bearish and candle body is not less than 10 points
#property indicator_chart_window #property indicator_plots 0 enum ENUM_SIGNAL { NO_SIGNAL = 0, BUY_SIGNAL = 1, SELL_SIGNAL = 2 }; class CSignalNotifier { public: void onCalculate(ENUM_SIGNAL signal); private: bool m_isPrevSignalUndef; ENUM_SIGNAL m_prevSignal; public: CSignalNotifier() : m_isPrevSignalUndef(true), m_prevSignal(NO_SIGNAL) {} }; CSignalNotifier notifier; int OnInit() { 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[]) { ArraySetAsSeries(open, true); ArraySetAsSeries(close, true); notifier.onCalculate(generateSomeSignal(open[0], close[0])); return(rates_total); } void CSignalNotifier::onCalculate(ENUM_SIGNAL signal) { if(m_isPrevSignalUndef) // First call of this method after attaching the indicator { m_isPrevSignalUndef = false; m_prevSignal = signal; return; } if(signal == m_prevSignal) // Signal hasn't changed - skip return; switch(signal) { case BUY_SIGNAL: case SELL_SIGNAL: m_prevSignal = signal; Alert(signal == BUY_SIGNAL ? "Buy" : "Sell"); break; //--- No signal - skip case NO_SIGNAL: return; //--- Protect against unexpected addition of values to an enumeration default: Print(__FUNCTION__" Unexpected signal: ", EnumToString(signal)); return; //--- } } #define _minBodySizeInt 10 ENUM_SIGNAL generateSomeSignal(double open, double close) { if(_minBodySizeInt * _Point - MathAbs(close - open) > _Point * 0.5) return(NO_SIGNAL); return(close > open ? BUY_SIGNAL : SELL_SIGNAL); } #undef _minBodySizeInt //---
My example works according to the following logic:
- Notify about buy signal if the previous notification was about sell signal;
- Notify about sell signal if the previous notification was about buy signal;
- If at the moment of attaching the indicator there was already a signal - ignore it (the next notification only when the opposite signal appears)
That's how I understand your logic. But such logic looks very strange to me.
thanks for the code, I am still beginner at OOP so I will learn it first. Sorry if you not understand my problem let me explain it again.
So, in my experience if I want to trigger alert from the signal only once instant at bar[0] I always write these
datetime time_alert; if(i == 0 && Time[0] != time_alert) Alert("Buy"); //Alert time_alert = Time[0];
But when the signal change from buy to sell at same bar[0], the alert only triggered once until new bar appear. Thus, I tried to remove i == 0 condition for the alert, and the new sell signal change alert triggered at new bar when the signal arrow at bar[1]. This condition fine by me, but new problem appeared. Everytime I compile the indicator, the alert always triggered. Because my lack of experience, I do not know what cause this problem
So, in my experience if I want to trigger alert from the signal only once instant at bar[0] I always write these
Sorry, I don't understand what you're trying to do. Don't describe your experience, but instead describe in words the rules for alerts (like I did for my example). When do you need an alert? What event must happen for this?
Pretend that you don’t know how to program and describe in ordinary human words when you need an alert.
Don't try to think in code right away. First formulate the task in human language, and only then start coding the finished logic.
Don't try to think in code right away. First formulate the task in human language, and only then start coding the finished logic.
I think it's better that I share you the full code of my indicator
#include <stdlib.mqh> #include <stderror.mqh> //--- indicator settings #property indicator_chart_window #property indicator_buffers 2 #property indicator_type1 DRAW_ARROW #property indicator_width1 3 #property indicator_color1 0xFF2B00 #property indicator_label1 "Buy" #property indicator_type2 DRAW_ARROW #property indicator_width2 3 #property indicator_color2 0x0000FF #property indicator_label2 "Sell" //--- indicator buffers double Buffer1[]; double Buffer2[]; extern int RSI_Period=3; extern int RSI_Level=70; extern int CCI_Period=4; extern int CCI_Level=125; datetime last_alert_time = 0; // Tracks the last alert time extern bool Audible_Alerts = true; double myPoint; //initialized in OnInit void myAlert(string type, string message) { if(type == "print") Print(message); else if(type == "error") { Print(type+" | DYMI_Alerts @ "+Symbol()+","+Period()+" | "+message); } else if(type == "order") { } else if(type == "modify") { } else if(type == "indicator") { Print(type+" | DYMI_Alerts @ "+Symbol()+","+Period()+" | "+message); if(Audible_Alerts) Alert(type+" | DYMI_Alerts @ "+Symbol()+","+Period()+" | "+message); } } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { IndicatorBuffers(4); SetIndexBuffer(0, Buffer1); SetIndexEmptyValue(0, 0); SetIndexArrow(0, 241); SetIndexBuffer(1, Buffer2); SetIndexEmptyValue(1, 0); SetIndexArrow(1, 242); //initialize myPoint myPoint = Point(); if(Digits() == 5 || Digits() == 3) { myPoint *= 10; } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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[]) { int limit = rates_total - prev_calculated; //--- counting from 0 to rates_total ArraySetAsSeries(Buffer1, true); ArraySetAsSeries(Buffer2, true); //--- initial zero if(prev_calculated < 1) { ArrayInitialize(Buffer1, 0); ArrayInitialize(Buffer2, 0); } else limit++; //--- main loop for (int i = limit - 1; i >= 0; i--) { if (i >= MathMin(5000 - 1, rates_total - 1 - 50)) continue; // omit old rates for performance // Buy Condition if (//iCustom(NULL, PERIOD_CURRENT, "DYMI", stdevLength, avgOfStdevLength, DYMILength, DYMILengthLowerLimit, DYMILengthUpperLimit, 0, i) > OVERSOLD iRSI(NULL, 0, RSI_Period, 0, i + 1) * 2 - 100 < -(RSI_Level) && iCCI(NULL, 0, CCI_Period, 0, i + 1) < -(CCI_Level)) { if (Close[i] < Open[i]) // If the candle is bearish, change to Sell signal { Buffer1[i] = 0; // Clear Buy signal Buffer2[i] = High[i] + iATR(NULL, PERIOD_CURRENT, 14, i); // Generate Sell signal if (time[0] != last_alert_time){Alert("Sell Signal Detected"); // Alert for Sell last_alert_time = time[0];} } else { Buffer2[i] = 0; // Clear Sell signal Buffer1[i] = Low[i] - iATR(NULL, PERIOD_CURRENT, 14, i); // Generate Buy signal if (time[0] != last_alert_time){Alert("Buy Signal Detected"); // Alert for Buy last_alert_time = time[0];} } } // Sell Condition if (//iCustom(NULL, PERIOD_CURRENT, "DYMI", stdevLength, avgOfStdevLength, DYMILength, DYMILengthLowerLimit, DYMILengthUpperLimit, 0, i) < OVERBOUGHT iRSI(NULL, 0, RSI_Period, 0, i + 1) * 2 - 100 > RSI_Level && iCCI(NULL, 0, CCI_Period, 0, i + 1) > CCI_Level) { if (Close[i] > Open[i]) // If the candle is bullish, change to Buy signal { Buffer2[i] = 0; // Clear Sell signal Buffer1[i] = Low[i] - iATR(NULL, PERIOD_CURRENT, 14, i); // Generate Buy signal if (time[0] != last_alert_time){Alert("Buy Signal Detected"); // Alert for Buy last_alert_time = time[0];} } else { Buffer1[i] = 0; // Clear Buy signal Buffer2[i] = High[i] + iATR(NULL, PERIOD_CURRENT, 14, i); // Generate Sell signal if (time[0] != last_alert_time){Alert("Sell Signal Detected"); // Alert for Sell last_alert_time = time[0];} } } } for (i = limit - 1; i >= 0; i--) { if(Buffer1[2] != 0 && Close[1] > Open[1]) { CreateArrow("ss",233,Low[0],Time[0],clrGreen,ANCHOR_TOP,1); } } return(rates_total); } //+------------------------------------------------------------------+ bool CreateArrow(const string name, const int code, const double price, const datetime time, const color col, const ENUM_ARROW_ANCHOR anc, const int size = 1) { bool create = ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0); ObjectSetInteger(0, name, OBJPROP_ARROWCODE, code); ObjectSetDouble(0, name, OBJPROP_PRICE, price); ObjectSetInteger(0, name, OBJPROP_TIME, time); ObjectSetInteger(0, name, OBJPROP_COLOR, col); ObjectSetInteger(0, name, OBJPROP_ANCHOR, anc); ObjectSetInteger(0, name, OBJPROP_WIDTH, size); return(create); }
you can try to put it on your chart and see why the alert triggered everytime we put it

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello, I want to ask if someone also has the similar problem. When I attach my indicator on the chart, alert comes up when there is no signal yet, here is my pseudocode
it was solved if I add the condition i == 0, but I do not want this because the indicator will not alert new signal if it repaints.