Code: Select all
//https://forex-station.com/viewtopic.php?t=8413435&p=1295393388#p1295393388
//------------------------------------------------------------------
#property copyright "mladen"
#property link "www.forex-tsd.com"
//------------------------------------------------------------------
#property indicator_separate_window
#property indicator_height 120
#property indicator_buffers 3
#property indicator_color1 clrDeepSkyBlue
#property indicator_color2 clrSandyBrown
#property indicator_color3 clrSandyBrown
#property indicator_width1 3
#property indicator_width2 3
#property indicator_width3 3
#property strict
//
//
//
//
//
enum enPrices
{
pr_close, // Close
pr_open, // Open
pr_high, // High
pr_low, // Low
pr_median, // Median
pr_typical, // Typical
pr_weighted, // Weighted
pr_average, // Average (high+low+open+close)/4
pr_medianb, // Average median body (open+close)/2
pr_tbiased, // Trend biased price
pr_haclose, // Heiken ashi close
pr_haopen , // Heiken ashi open
pr_hahigh, // Heiken ashi high
pr_halow, // Heiken ashi low
pr_hamedian, // Heiken ashi median
pr_hatypical, // Heiken ashi typical
pr_haweighted, // Heiken ashi weighted
pr_haaverage, // Heiken ashi average
pr_hamedianb, // Heiken ashi median body
pr_hatbiased // Heiken ashi trend biased price
};
extern int mkperiod = 14; // Kahler smoothing period
extern int mfperiod = 12; // Macd fast period
extern int msperiod = 26; // Macd slow period
extern int mtperiod = 9; // Macd signal period
extern enPrices price = pr_close; // Price
extern int linesWidth = 4; // Lines width
extern double fastr = 8; // Fast ratio
extern double slowr = 22; // Slow ratio
extern bool alertsOn = false; // Turn alerts on
extern bool alertsOnCurrent = false; // Alerts on currnt (still opened) bar
extern bool alertsMessage = true; // Alerts should show pop-up message
extern bool alertsSound = true; // Alerts should play alert sound
extern bool alertsPushNotif = false; // Alerts should send push notification
extern bool alertsEmail = false; // Alerts should send email
extern bool showArrows = false; // Display arrows on chart?
extern string arrowsIdentifier = "MacdDKArrows1"; // Unique identifier for arrows
extern double arrowsUpperGap = 0.5; // Upper arrow gap
extern double arrowsLowerGap = 0.5; // Lower arrow gap
extern color arrowsUpColor = clrDeepSkyBlue; // Upper arrow color
extern color arrowsDnColor = clrSandyBrown; // Lower arrow color
extern int arrowsUpCode = 124; // Upper arrow code
extern int arrowsDnCode = 124; // Lower arrow code
double buffer[];
double bufferda[];
double bufferdb[];
double trend[];
double macd[];
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
int init()
{
IndicatorBuffers(5);
SetIndexBuffer(0,buffer, INDICATOR_DATA); SetIndexStyle(0,EMPTY,EMPTY,linesWidth);
SetIndexBuffer(1,bufferda,INDICATOR_DATA); SetIndexStyle(1,EMPTY,EMPTY,linesWidth);
SetIndexBuffer(2,bufferdb,INDICATOR_DATA); SetIndexStyle(2,EMPTY,EMPTY,linesWidth);
SetIndexBuffer(3,trend ,INDICATOR_CALCULATIONS);
SetIndexBuffer(4,macd ,INDICATOR_CALCULATIONS);
IndicatorShortName("macd digital Kahler ("+(string)mkperiod+","+(string)mfperiod+","+(string)msperiod+(string)mtperiod+","+")");
return(0);
}
int deinit()
{
string lookFor = arrowsIdentifier+":";
int lookForLength = StringLen(lookFor);
for (int i=ObjectsTotal()-1; i>=0; i--)
{
string objectName = ObjectName(i);
if (StringSubstr(objectName,0,lookForLength) == lookFor) ObjectDelete(objectName);
}
return(0);
}
//
//
//
//
//
int start()
{
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=MathMin(Bars-counted_bars,Bars-2);
//
//
//
//
//
if (trend[limit]==-1) CleanPoint(limit,bufferda,bufferdb);
for(int i=limit; i>=0; i--) macd[i] = calculateTma(getPrice(price,Open,Close,High,Low,i),mfperiod,i,1)-calculateTma(getPrice(price,Open,Close,High,Low,i),msperiod,i,2);
for(int i=limit; i>=0; i--)
{
double fast_k = macd[i];
double slow_k = iMAOnArray(macd,0,mtperiod,0,i);
double temp = 0;
if ((slowr*slow_k+fastr*fast_k)/(fastr+slowr)>0.0) temp= 1;
if ((slowr*slow_k+fastr*fast_k)/(fastr+slowr)<0.0) temp=-1;
buffer[i] = calculateTma(temp,mkperiod,i);
bufferda[i] = EMPTY_VALUE;
bufferdb[i] = EMPTY_VALUE;
trend[i] = trend[i+1];
//
//
//
//
//
if (buffer[i]>buffer[i+1]) trend[i] = 1;
if (buffer[i]<buffer[i+1]) trend[i] = -1;
if (trend[i] == -1) PlotPoint(i,bufferda,bufferdb,buffer);
if (showArrows)
{
ObjectDelete(arrowsIdentifier+":"+(string)Time[i]);
if (trend[i] != trend[i+1])
{
if (trend[i] == 1) drawArrow(i,arrowsUpColor,arrowsUpCode,false);
if (trend[i] ==-1) drawArrow(i,arrowsDnColor,arrowsDnCode, true);
}
}
}
manageAlerts();
return(0);
}
//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
//
//
//
//
//
void drawArrow(int i,color theColor,int theCode,bool up)
{
string name = arrowsIdentifier+":"+(string)Time[i];
double gap = iATR(NULL,0,20,i);
//
//
//
//
//
ObjectCreate(name,OBJ_ARROW,0,Time[i],0);
ObjectSet(name,OBJPROP_ARROWCODE,theCode);
ObjectSet(name,OBJPROP_COLOR,theColor);
if (up)
ObjectSet(name,OBJPROP_PRICE1,High[i] + arrowsUpperGap * gap);
else ObjectSet(name,OBJPROP_PRICE1,Low[i] - arrowsLowerGap * gap);
}
//
//
//
//
//
void manageAlerts()
{
if (alertsOn)
{
int whichBar = 1; if (alertsOnCurrent) whichBar = 0;
if (trend[whichBar] != trend[whichBar+1])
{
if (trend[whichBar] == 1) doAlert(whichBar,"up");
if (trend[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 = Symbol()+" at "+TimeToStr(TimeLocal(),TIME_SECONDS)+" macd digital Kahler slope changed to "+doWhat;
if (alertsMessage) Alert(message);
if (alertsEmail) SendMail(Symbol()+" macd digital Kahler",message);
if (alertsPushNotif) SendNotification(message);
if (alertsSound) PlaySound("alert2.wav");
}
}
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------
double calculateTma(double tprice[], int halfLength, int i)
{
int j, k;
double sum = (halfLength+1)*tprice[i];
double sumw = (halfLength+1);
for(j=1, k=halfLength; j<=halfLength; j++, k--)
{
sum += k*tprice[i+j];
sumw += k;
if (j<=i)
{
sum += k*tprice[i-j];
sumw += k;
}
}
//+++
return(sum/sumw);
}
//-------------------------------------------------------------------
//
//
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CleanPoint(int i,double& first,double& second[])
{
if ((second[i] != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
second[i+1] = EMPTY_VALUE;
else
if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
first[i+1] = EMPTY_VALUE;
}
//+++==========
void PlotPoint(int i,double& first[],double& second[],double& from[])
{
if (first[i+1] == EMPTY_VALUE)
{
if (first[i+2] == EMPTY_VALUE)
{
first[i] = from[i];
first[i+1] = from[i+1];
second[i] = EMPTY_VALUE;
}
else
{
second[i] = from[i];
second[i+1] = from[i+1];
first[i] = EMPTY_VALUE;
}
}
else
{
first[i] = from[i];
second[i] = EMPTY_VALUE;
}
}///////////////////////////////////////////////////////////////////
//
//
//
//
//
//------------------------------------------------------------------
//
//
//
//
//
//
double workHa[][4];
double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int instanceNo=0)
{
if (tprice>=pr_haclose)
{
if (ArrayRange(workHa,0)!= Bars) ArrayResize(workHa,Bars);
int r = Bars-i-1;
//
//
//
//
//
double haOpen;
if (r>0)
haOpen = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;
else haOpen = (open[i]+close[i])/2;
double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;
double haHigh = MathMax(high[i], MathMax(haOpen,haClose));
double haLow = MathMin(low[i] , MathMin(haOpen,haClose));
if(haOpen <haClose) { workHa[r][instanceNo+0] = haLow; workHa[r][instanceNo+1] = haHigh; }
else { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow; }
workHa[r][instanceNo+2] = haOpen;
workHa[r][instanceNo+3] = haClose;
//
//
//
//
//
switch (tprice)
{
case pr_haclose: return(haClose);
case pr_haopen: return(haOpen);
case pr_hahigh: return(haHigh);
case pr_halow: return(haLow);
case pr_hamedian: return((haHigh+haLow)/2.0);
case pr_hamedianb: return((haOpen+haClose)/2.0);
case pr_hatypical: return((haHigh+haLow+haClose)/3.0);
case pr_haweighted: return((haHigh+haLow+haClose+haClose)/4.0);
case pr_haaverage: return((haHigh+haLow+haClose+haOpen)/4.0);
case pr_hatbiased:
if (haClose>haOpen)
return((haHigh+haClose)/2.0);
else return((haLow+haClose)/2.0);
}
}
//
//
//
//
//
switch (tprice)
{
case pr_close: return(close[i]);
case pr_open: return(open[i]);
case pr_high: return(high[i]);
case pr_low: return(low[i]);
case pr_median: return((high[i]+low[i])/2.0);
case pr_medianb: return((open[i]+close[i])/2.0);
case pr_typical: return((high[i]+low[i]+close[i])/3.0);
case pr_weighted: return((high[i]+low[i]+close[i]+close[i])/4.0);
case pr_average: return((high[i]+low[i]+close[i]+open[i])/4.0);
case pr_tbiased:
if (close[i]>open[i])
return((high[i]+close[i])/2.0);
else return((low[i]+close[i])/2.0);
}
return(0);
}