差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
| mt4:mt4_的报警指标 [2022/10/05 11:11] – wyrover | mt4:mt4_的报警指标 [2022/10/05 11:36] (当前版本) – wyrover | ||
|---|---|---|---|
| 行 9: | 行 9: | ||
| - On-screen | - On-screen | ||
| + | 这里 [Moving Average Crossover with Alert for MT4 and MT5](https:// | ||
| + | <code cpp> | ||
| + | #property link " | ||
| + | #property version | ||
| + | #property strict | ||
| + | #property copyright | ||
| + | #property description | ||
| + | #property description | ||
| + | #property description | ||
| + | #property description | ||
| + | #property description | ||
| + | #property icon " | ||
| + | |||
| + | #property indicator_chart_window | ||
| + | #property indicator_buffers 2 | ||
| + | #property indicator_color1 clrRed | ||
| + | #property indicator_color2 clrGreen | ||
| + | #property indicator_type1 DRAW_LINE | ||
| + | #property indicator_type2 DRAW_LINE | ||
| + | #property indicator_label1 "Fast MA" | ||
| + | #property indicator_label2 "Slow MA" | ||
| + | |||
| + | #include <MQLTA ErrorHandling.mqh> | ||
| + | #include <MQLTA Utils.mqh> | ||
| + | |||
| + | enum ENUM_TRADE_SIGNAL { | ||
| + | SIGNAL_BUY = 1, // Buy | ||
| + | SIGNAL_SELL = -1, // Sell | ||
| + | SIGNAL_NEUTRAL = 0 // Neutral | ||
| + | }; | ||
| + | |||
| + | enum ENUM_CANDLE_TO_CHECK { | ||
| + | CURRENT_CANDLE = 0, // Current candle | ||
| + | CLOSED_CANDLE = 1 // Previous candle | ||
| + | }; | ||
| + | |||
| + | input string Comment1 = " | ||
| + | input string IndicatorName = " | ||
| + | |||
| + | input string Comment2 = " | ||
| + | input int MAFastPeriod = 144; // Fast moving average period | ||
| + | input int MAFastShift = 0; // Fast moving average shift | ||
| + | input ENUM_MA_METHOD MAFastMethod = MODE_EMA; | ||
| + | input ENUM_APPLIED_PRICE MAFastAppliedPrice = PRICE_CLOSE; | ||
| + | input int MASlowPeriod = 576; // Slow moving average period | ||
| + | input int MASlowShift = 0; // Slow moving average shift | ||
| + | input ENUM_MA_METHOD MASlowMethod = MODE_EMA; | ||
| + | input ENUM_APPLIED_PRICE MASlowAppliedPrice = PRICE_CLOSE; | ||
| + | input ENUM_CANDLE_TO_CHECK CandleToCheck = CURRENT_CANDLE; | ||
| + | input int BarsToScan = 2000; // Number of candles to analyze | ||
| + | |||
| + | input string Comment_3 = " | ||
| + | input bool EnableNotify = true; // Enable notifications feature | ||
| + | input bool SendAlert = true; // Send alert notification | ||
| + | input bool SendApp = false; | ||
| + | input bool SendEmail = false; | ||
| + | |||
| + | input string Comment_4 = " | ||
| + | input bool EnableDrawArrows = true; // Draw signal arrows | ||
| + | input int ArrowBuy = 241; // Buy arrow code | ||
| + | input int ArrowSell = 242; // Sell arrow code | ||
| + | input int ArrowSize = 3; // Arrow size (1-5) | ||
| + | input color ArrowBuyColor = clrGreen; | ||
| + | input color ArrowSellColor = clrRed; | ||
| + | |||
| + | double BufferMASlow[]; | ||
| + | double BufferMAFast[]; | ||
| + | |||
| + | datetime LastNotificationTime; | ||
| + | ENUM_TRADE_SIGNAL LastNotificationDirection; | ||
| + | int Shift = 0; | ||
| + | |||
| + | int OnInit(void) { | ||
| + | |||
| + | IndicatorSetString(INDICATOR_SHORTNAME, | ||
| + | |||
| + | OnInitInitialization(); | ||
| + | if (!OnInitPreChecksPass()) { | ||
| + | return INIT_FAILED; | ||
| + | } | ||
| + | |||
| + | InitialiseBuffers(); | ||
| + | |||
| + | return INIT_SUCCEEDED; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | int OnCalculate(const int rates_total, | ||
| + | const int prev_calculated, | ||
| + | const datetime & | ||
| + | const double & | ||
| + | const double & | ||
| + | const double &low[], | ||
| + | const double & | ||
| + | const long & | ||
| + | const long & | ||
| + | const int & | ||
| + | if ((rates_total <= MASlowPeriod) || (MASlowPeriod <= 0)) return 0; | ||
| + | if ((rates_total <= MAFastPeriod) || (MAFastPeriod <= 0)) return 0; | ||
| + | if (MAFastPeriod > MASlowPeriod) return 0; | ||
| + | |||
| + | bool IsNewCandle = CheckIfNewCandle(); | ||
| + | |||
| + | if (Bars(Symbol(), | ||
| + | Print(" | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | int pos = 0, upTo; | ||
| + | if ((prev_calculated == 0) || (IsNewCandle)) { | ||
| + | upTo = BarsToScan - 1; | ||
| + | } else { | ||
| + | upTo = 0; | ||
| + | } | ||
| + | |||
| + | for (int i = pos; (i <= upTo) && (!IsStopped()); | ||
| + | BufferMASlow[i] = iMA(Symbol(), | ||
| + | BufferMAFast[i] = iMA(Symbol(), | ||
| + | } | ||
| + | |||
| + | if ((IsNewCandle) || (prev_calculated == 0)) { | ||
| + | if (EnableDrawArrows) DrawArrows(); | ||
| + | } | ||
| + | |||
| + | if (EnableDrawArrows) DrawArrow(0); | ||
| + | |||
| + | if (EnableNotify) NotifyHit(); | ||
| + | |||
| + | return rates_total; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void OnDeinit(const int reason) { | ||
| + | CleanChart(); | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void OnInitInitialization() { | ||
| + | LastNotificationTime = TimeCurrent(); | ||
| + | LastNotificationDirection = SIGNAL_NEUTRAL; | ||
| + | Shift = CandleToCheck; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | bool OnInitPreChecksPass() { | ||
| + | if ((MASlowPeriod <= 0) || (MAFastPeriod <= 0) || (MAFastPeriod > MASlowPeriod)) { | ||
| + | Print(" | ||
| + | return false; | ||
| + | } | ||
| + | return true; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void CleanChart() { | ||
| + | ObjectsDeleteAll(ChartID(), | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void InitialiseBuffers() { | ||
| + | SetIndexBuffer(0, | ||
| + | SetIndexShift(0, | ||
| + | SetIndexDrawBegin(0, | ||
| + | SetIndexBuffer(1, | ||
| + | SetIndexShift(1, | ||
| + | SetIndexDrawBegin(1, | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | datetime NewCandleTime = TimeCurrent(); | ||
| + | bool CheckIfNewCandle() { | ||
| + | if (NewCandleTime == iTime(Symbol(), | ||
| + | else { | ||
| + | NewCandleTime = iTime(Symbol(), | ||
| + | return true; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | //Check if it is a trade Signla 0 - Neutral, 1 - Buy, -1 - Sell | ||
| + | ENUM_TRADE_SIGNAL IsSignal(int i) { | ||
| + | int j = i + Shift; | ||
| + | if(BufferMAFast[j + 1] < BufferMASlow[j + 1] && BufferMAFast[j] > BufferMASlow[j]) return SIGNAL_BUY; | ||
| + | if(BufferMAFast[j + 1] > BufferMASlow[j + 1] && BufferMAFast[j] < BufferMASlow[j]) return SIGNAL_SELL; | ||
| + | |||
| + | return SIGNAL_NEUTRAL; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void NotifyHit() { | ||
| + | if (!EnableNotify) return; | ||
| + | if ((!SendAlert) && (!SendApp) && (!SendEmail)) return; | ||
| + | if ((CandleToCheck == CLOSED_CANDLE) && (Time[0] <= LastNotificationTime)) return; | ||
| + | ENUM_TRADE_SIGNAL Signal = IsSignal(0); | ||
| + | if (Signal == SIGNAL_NEUTRAL) { | ||
| + | LastNotificationDirection = Signal; | ||
| + | return; | ||
| + | } | ||
| + | if (Signal == LastNotificationDirection) return; | ||
| + | string EmailSubject = IndicatorName + " " + Symbol() + " Notification "; | ||
| + | string EmailBody = AccountCompany() + " - " + AccountName() + " - " + IntegerToString(AccountNumber()) + " | ||
| + | string AlertText = IndicatorName + " - " + Symbol() + " @ " + EnumToString((ENUM_TIMEFRAMES)Period()) + " "; | ||
| + | string AppText = AccountCompany() + " - " + AccountName() + " - " + IntegerToString(AccountNumber()) + " - " + IndicatorName + " - " + Symbol() + " @ " + EnumToString((ENUM_TIMEFRAMES)Period()) + " - "; | ||
| + | string Text = ""; | ||
| + | |||
| + | Text += "Slow and Fast Moving Average Crossed - " + ((Signal == SIGNAL_SELL) ? " | ||
| + | |||
| + | EmailBody += Text; | ||
| + | AlertText += Text; | ||
| + | AppText += Text; | ||
| + | if (SendAlert) Alert(AlertText); | ||
| + | if (SendEmail) { | ||
| + | if (!SendMail(EmailSubject, | ||
| + | } | ||
| + | if (SendApp) { | ||
| + | if (!SendNotification(AppText)) Print(" | ||
| + | } | ||
| + | LastNotificationTime = Time[0]; | ||
| + | LastNotificationDirection = Signal; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void DrawArrows() { | ||
| + | RemoveArrows(); | ||
| + | if(!EnableDrawArrows || BarsToScan == 0) return; | ||
| + | if ((!EnableDrawArrows) || (BarsToScan == 0)) return; | ||
| + | int MaxBars = Bars(Symbol(), | ||
| + | if (MaxBars > BarsToScan) MaxBars = BarsToScan; | ||
| + | for (int i = MaxBars - 2; i >= 1; i--) { | ||
| + | DrawArrow(i); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void RemoveArrows() { | ||
| + | ObjectsDeleteAll(ChartID(), | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void DrawArrow(int i) { | ||
| + | RemoveArrowCurr(); | ||
| + | if (!EnableDrawArrows) { | ||
| + | RemoveArrows(); | ||
| + | return; | ||
| + | } | ||
| + | ENUM_TRADE_SIGNAL Signal = IsSignal(i); | ||
| + | if (Signal == SIGNAL_NEUTRAL) return; | ||
| + | datetime ArrowDate = iTime(Symbol(), | ||
| + | string ArrowName = IndicatorName + " | ||
| + | double ArrowPrice = 0; | ||
| + | int ArrowType = 0; | ||
| + | color ArrowColor = 0; | ||
| + | int ArrowAnchor = 0; | ||
| + | string ArrowDesc = ""; | ||
| + | if (Signal == SIGNAL_BUY) { | ||
| + | ArrowPrice = Low[i]; | ||
| + | ArrowType = ArrowBuy; | ||
| + | ArrowColor = ArrowBuyColor; | ||
| + | ArrowAnchor = ANCHOR_TOP; | ||
| + | ArrowDesc = " | ||
| + | } | ||
| + | if(Signal == SIGNAL_SELL) { | ||
| + | ArrowPrice = High[i]; | ||
| + | ArrowType = ArrowSell; | ||
| + | ArrowColor = ArrowSellColor; | ||
| + | ArrowAnchor = ANCHOR_BOTTOM; | ||
| + | ArrowDesc = " | ||
| + | } | ||
| + | ObjectCreate(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetInteger(0, | ||
| + | ObjectSetString(0, | ||
| + | } | ||
| + | |||
| + | // | ||
| + | //| | | ||
| + | // | ||
| + | void RemoveArrowCurr() { | ||
| + | datetime ArrowDate = iTime(Symbol(), | ||
| + | string ArrowName = IndicatorName + " | ||
| + | ObjectDelete(0, | ||
| + | } | ||
| + | // | ||
| + | // | ||
| + | |||
| + | </ | ||