//+------------------------------------------------------------------+ //| WeisWave3.mq4 | //| This code comes as is and carries NO WARRANTY whatsoever | //| Use at your own risk! | //+------------------------------------------------------------------+ #property strict #property indicator_separate_window #property indicator_minimum 0 #property indicator_buffers 2 #property indicator_plots 2 //--- plot upVolume #property indicator_label1 "upVolume" #property indicator_type1 DRAW_HISTOGRAM #property indicator_color1 clrGreen #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- plot dnVolume #property indicator_label2 "dnVolume" #property indicator_type2 DRAW_HISTOGRAM #property indicator_color2 clrFireBrick #property indicator_style2 STYLE_SOLID #property indicator_width2 2 //#property indicator_label3 "upPip" //#property indicator_type1 DRAW_LINE //#property indicator_color1 clrBlue //#property indicator_style1 STYLE_SOLID //#property indicator_width1 2 //--- plot dnVolume //#property indicator_label4 "dnPip" //#property indicator_type2 DRAW_LINE //#property indicator_color2 clrRed //#property indicator_width2 2 //--- input parameters input int Difference = 30; input int LabelShift = 15; input bool ShowVolumeLabels = true; input int FontSize = 7; input color FontColorUp = clrBlue; input color FontColorDn = clrRed; // input int DivBy = 1; input color WaveColor = clrBlack; input int WaveWidth = 1; input bool alertsOn = true; // Turn alerts on/off? input bool alertsOnCurrent = false; // Alerts on open bar on/off? input bool alertsMessage = true; // Alerts message on/off? input bool alertsSound = false; // Alerts sound on/off? input bool alertsNotify = false; // Alerts notification on/off? input bool alertsEmail = false; // Alerts email on/off? input string soundFile = "alert2.wav"; // Sound file //--- indicator buffers double upVolumeBuffer[]; double dnVolumeBuffer[]; double barDirection[]; double trendDirection[]; double waveDirection[]; double upPipBuffer[]; double dnPipBuffer[]; long volumeTracker = 0; long pipTracker=0; double highestHigh = EMPTY_VALUE; double lowestLow = EMPTY_VALUE; int hhBar = EMPTY_VALUE; int llBar = EMPTY_VALUE; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping IndicatorBuffers(75); SetIndexBuffer(0, upVolumeBuffer); SetIndexBuffer(1, dnVolumeBuffer); SetIndexBuffer(2, upPipBuffer); SetIndexBuffer(3, dnPipBuffer); SetIndexBuffer(4, trendDirection); SetIndexBuffer(5, waveDirection); SetIndexBuffer(6, barDirection); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { for(int i = ObjectsTotal() - 1; i >= 0; i--) { string Label = ObjectName(i); if (StringCompare("ED8847DC", StringSubstr(Label, 0, 8), true) == 0) { ObjectDelete(Label); } } return(0); } //+------------------------------------------------------------------+ //| 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[]) { //--- // Only compute bars on new bar if (rates_total == prev_calculated) return(rates_total); RefreshRates(); int limit = rates_total - 2; int waveChangeBar = limit - 2; // Initialise values if (highestHigh == EMPTY_VALUE) highestHigh = close[waveChangeBar]; if (lowestLow == EMPTY_VALUE) lowestLow = close[waveChangeBar]; if (hhBar == EMPTY_VALUE) hhBar = waveChangeBar; if (llBar == EMPTY_VALUE) llBar = waveChangeBar; string waveID = "ED8847DC-" + TimeToString(time[waveChangeBar], TIME_DATE|TIME_MINUTES) + "-TL"; if (!ObjectFind(0, waveID)) { ObjectCreate(0, waveID, OBJ_TREND, 0, time[waveChangeBar], close[waveChangeBar], time[waveChangeBar], close[waveChangeBar]); ObjectSet(waveID, OBJPROP_RAY, false); ObjectSet(waveID, OBJPROP_WIDTH, WaveWidth); ObjectSet(waveID, OBJPROP_COLOR, WaveColor); } double shift = LabelShift / MathPow(10, Digits); for(int i=limit-1; i>=0; i--) { // Determine this bar's direction if (close[i] - close[i+1] > 0) barDirection[i] = 1; // current close higher if (close[i] - close[i+1] == 0) barDirection[i] = 0; // current close equal if (close[i] - close[i+1] < 0) barDirection[i] = -1; // current close lower if (barDirection[limit] == EMPTY_VALUE) barDirection[limit] = barDirection[i]; if (trendDirection[limit] == EMPTY_VALUE) trendDirection[limit] = barDirection[i]; if (waveDirection[limit] == EMPTY_VALUE) waveDirection[limit] = barDirection[i]; // Determine highset high and lowest low if (close[i] > highestHigh) { highestHigh = close[i]; hhBar = i; } else if (close[i] < lowestLow) { lowestLow = close[i]; llBar = i; } // Determine if this bar has started a new trend if ((barDirection[i] != 0) && (barDirection[i] != barDirection[i+1])) trendDirection[i] = barDirection[i]; else trendDirection[i] = trendDirection[i+1]; // Determine if this bar has started a new wave double waveTest = 0.0; if (waveDirection[i+1] == 1) { waveTest = highestHigh; } if (waveDirection[i+1] == -1) { waveTest = lowestLow; } double waveDifference = (MathAbs(waveTest - close[i])) * MathPow(10, Digits); if (trendDirection[i] != waveDirection[i+1]) { if (waveDifference >= Difference) waveDirection[i] = trendDirection[i]; else waveDirection[i] = waveDirection[i+1]; } else waveDirection[i] = waveDirection[i+1]; // Determine if we have started a new wave if (waveDirection[i] != waveDirection[i+1]) { if (waveDirection[i] == 1) { highestHigh = close[i]; hhBar = i; waveChangeBar = llBar; } else { lowestLow = close[i]; llBar = i; waveChangeBar = hhBar; } ObjectSet(waveID, OBJPROP_PRICE2, close[waveChangeBar]); ObjectSet(waveID, OBJPROP_TIME2, time[waveChangeBar]); waveID = "ED8847DC-" + TimeToString(time[waveChangeBar], TIME_DATE|TIME_MINUTES) + "-TL"; ObjectCreate(0, waveID, OBJ_TREND, 0, time[waveChangeBar], close[waveChangeBar], time[i], close[i]); ObjectSet(waveID, OBJPROP_RAY, false); ObjectSet(waveID, OBJPROP_WIDTH, WaveWidth); ObjectSet(waveID, OBJPROP_COLOR, WaveColor); volumeTracker = 0; pipTracker=0; for (int k=waveChangeBar-1; k>=i; k--) { volumeTracker += tick_volume[k]; pipTracker += (open[k]-close[k])/Point; if (waveDirection[i] == 1) { upVolumeBuffer[k] = volumeTracker; dnVolumeBuffer[k] = 0; upPipBuffer[k]=MathAbs(pipTracker); dnPipBuffer[k]=0; } if (waveDirection[i] == -1) { upVolumeBuffer[k] = 0; dnVolumeBuffer[k] = volumeTracker; upPipBuffer[k]=0; dnPipBuffer[k]=MathAbs(pipTracker); } } if (ShowVolumeLabels == true) { string volLabel = "ED8847DC-" + TimeToString(time[waveChangeBar], TIME_DATE|TIME_MINUTES) + "-VOL"; if (waveDirection[i] == 1) { ObjectCreate(0, volLabel, OBJ_TEXT, 0, time[waveChangeBar], low[waveChangeBar]-shift); ObjectSet(volLabel, OBJPROP_ANGLE, -0); ObjectSet(volLabel, OBJPROP_ANCHOR, ANCHOR_CENTER); // ObjectSetText(volLabel, DoubleToString(dnVolumeBuffer[waveChangeBar]/DivBy, 0), 8, NULL, clrLightPink); ObjectSetText(volLabel,StringConcatenate(DoubleToString(dnPipBuffer[waveChangeBar]/10, 0),"-", DoubleToString(dnVolumeBuffer[waveChangeBar]/1000, 1),"K"), FontSize, NULL, FontColorDn); } else{ ObjectCreate(0, volLabel, OBJ_TEXT, 0, time[waveChangeBar], high[waveChangeBar]+shift); ObjectSet(volLabel, OBJPROP_ANGLE, 0); ObjectSet(volLabel, OBJPROP_ANCHOR, ANCHOR_CENTER); // ObjectSetText(volLabel, DoubleToString(upVolumeBuffer[waveChangeBar]/DivBy, 0), 8, NULL, clrLightGreen); ObjectSetText(volLabel, StringConcatenate(DoubleToString(upPipBuffer[waveChangeBar]/10, 0),"-", DoubleToString(upVolumeBuffer[waveChangeBar]/1000, 1),"K"), FontSize, NULL, FontColorUp); } } } else { volumeTracker += tick_volume[i]; pipTracker+=(open[i]-close[i]) /Point ; } // Set the indicators if (waveDirection[i] == 1) { upVolumeBuffer[i] = volumeTracker; dnVolumeBuffer[i] = 0; upPipBuffer[i]=MathAbs(pipTracker); dnPipBuffer[i]=0; } if (waveDirection[i] == -1) { upVolumeBuffer[i] = 0; dnVolumeBuffer[i] = volumeTracker; upPipBuffer[i]=0; dnPipBuffer[i]=MathAbs(pipTracker); } } ObjectSet(waveID, OBJPROP_PRICE2, close[0]); ObjectSet(waveID, OBJPROP_TIME2, time[0]); manageAlerts(); //--- return value of prev_calculated for next call return(rates_total); } string StringPadLeft (string inStr, ushort padStr, int totalStrLen) { string result; StringInit(result, totalStrLen, padStr); result = StringConcatenate(result, inStr); int pos = StringLen(inStr); return StringSubstr(result, pos, totalStrLen); } //+------------------------------------------------------------------- //| //+------------------------------------------------------------------- // // // // // string sTfTable[] = {"M1","M5","M15","M30","H1","H4","D1","W1","MN"}; int iTfTable[] = {1,5,15,30,60,240,1440,10080,43200}; string timeFrameToString(int tf) { for (int i=ArraySize(iTfTable)-1; i>=0; i--) if (tf==iTfTable[i]) return(sTfTable[i]); return(""); } // // // // // void manageAlerts() { if (alertsOn) { int whichBar = 1; if (alertsOnCurrent) whichBar = 0; if (waveDirection[whichBar] != waveDirection[whichBar+1]) { if (waveDirection[whichBar] == 1) doAlert(whichBar," up"); if (waveDirection[whichBar] == -1) doAlert(whichBar," down"); } } } // // // // // void doAlert(int forBar, string doWhat) { static string previousAlert="nothing"; static datetime previousTime; string message; if (previousAlert != doWhat || previousTime != Time[forBar]) { previousAlert = doWhat; previousTime = Time[forBar]; // // // // // message = timeFrameToString(_Period)+" "+_Symbol+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" Weis Wave "+doWhat; if (alertsMessage) Alert(message); if (alertsNotify) SendNotification(message); if (alertsEmail) SendMail(_Symbol+" Weis Wave ",message); if (alertsSound) PlaySound(soundFile); } }