差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
mt4:mt4_的报警指标 [2022/10/05 11:13] – 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:// | + | 这里 [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, | ||
+ | } | ||
+ | // | ||
+ | // | ||
+ | |||
+ | </ |