//+------------------------------------------------------------------+
//| Phase Adaptive_v1.0 600+.mq4 |
//| Copyright © 2016, TrendLaboratory |
//| http://finance.groups.yahoo.com/group/TrendLaboratory |
//| E-mail: igorad2003@yahoo.co.uk |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, TrendLaboratory"
#property link "http://finance.groups.yahoo.com/group/TrendLaboratory"
#property link "http://newdigital-world.com/forum.php"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 clrDeepSkyBlue
#property indicator_width1 2
#property indicator_level1 90
#property indicator_level2 180
#property indicator_level3 270
#property indicator_minimum 0
#property indicator_maximum 360
enum ENUM_PRICE
{
close, // Close
open, // Open
high, // High
low, // Low
median, // Median
typical, // Typical
weightedClose, // Weighted Close
heikenAshiClose, // Heiken Ashi Close
heikenAshiOpen, // Heiken Ashi Open
heikenAshiHigh, // Heiken Ashi High
heikenAshiLow, // Heiken Ashi Low
heikenAshiMedian, // Heiken Ashi Median
heikenAshiTypical, // Heiken Ashi Typical
heikenAshiWeighted // Heiken Ashi Weighted Close
};
#define pi 3.14159265358979323846
//---- input parameters
input ENUM_TIMEFRAMES TimeFrame = 0; // Timeframe
input ENUM_PRICE Price = 0; // Price
input double CyclePeriod = 15; // Cycle Period Ratio
input bool AdaptiveModeOn = false; // Adaptive Mode On/Off
input double Alpha = 0.07; // Cycle Smoothing Factor(eg. 0.07)
input int MedianPeriod = 5; // Period of Moving Median
input int DCsmooth = 5; // Period of Dominant Cycle Smoothing
//---- buffers
double phase[];
double iprice[];
int timeframe, draw_begin;
string TF, IndicatorName;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
timeframe = TimeFrame;
if(timeframe <= Period()) timeframe = Period();
TF = tf(timeframe);
IndicatorDigits(5);
//---- indicators
IndicatorBuffers(2);
SetIndexBuffer(0, phase); SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(1,iprice);
//----
IndicatorName = WindowExpertName();
IndicatorShortName(IndicatorName+"["+TF+"]("+Price+","+DoubleToStr(CyclePeriod,2)+")");
SetIndexLabel(0,"Phase");
//----
draw_begin = MathMax(2,Bars - iBars(NULL,timeframe)*timeframe/Period() + 50);
SetIndexDrawBegin(0,draw_begin);
return(0);
}
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| Phase Adaptive_v1.0 600+ |
//+------------------------------------------------------------------+
int start()
{
int shift, limit, counted_bars=IndicatorCounted();
//----
if(counted_bars > 0) limit = Bars - counted_bars - 1;
if(counted_bars < 0) return(0);
if(counted_bars < 1)
{
limit = Bars - 1;
for(int i=limit;i>=0;i--)
{
phase = EMPTY_VALUE;
}
}
if(timeframe != Period())
{
limit = MathMax(limit,timeframe/Period());
for(shift = 0;shift < limit;shift++)
{
int y = iBarShift(NULL,timeframe,Time[shift]);
phase[shift] = iCustom(NULL,TimeFrame,IndicatorName,0,Price,CyclePeriod,AdaptiveModeOn,Alpha,MedianPeriod,DCsmooth,0,y);
}
return(0);
}
else _adaptivePhase(limit);
//----
return(0);
}
//+------------------------------------------------------------------+
void _adaptivePhase(int limit)
{
double ;
for(int shift=limit;shift>=0;shift--)
{
if(Price <= 6) iprice[shift] = iMA(NULL,0,1,0,0,(int)Price,shift);
else
if(Price > 6 && Price <= 13) iprice[shift] = HeikenAshi(0,(int)Price-7,shift);
if(AdaptiveModeOn)
{
double cyclelen = cyclePeriod(iprice,Alpha,MedianPeriod,DCsmooth,shift);
int domcycle = MathMax(1,MathFloor(CyclePeriod*cyclelen));
}
else domcycle = MathMax(1,MathFloor(CyclePeriod));
double realPart = 0;
double imagPart = 0;
for(int i=0;i<domcycle;i++)
{
if(domcycle > 0)
{
double weight = iprice[shift+i];
realPart += MathCos(2*pi*i/domcycle)*weight;
imagPart += MathSin(2*pi*i/domcycle)*weight;
}
}
if(MathAbs(realPart) > 0.001) phase[shift] = MathArctan(imagPart/realPart); else phase[shift] = 0.5*pi*Sign(imagPart);
if(realPart < 0) phase[shift] = phase[shift] + pi;
phase[shift] = phase[shift] + pi/2;
if(phase[shift] < 0) phase[shift] = phase[shift] + 2*pi;
if(phase[shift] > 2*pi) phase[shift] = phase[shift] - 2*pi;
phase[shift] = 180*phase[shift]/pi;
}
}
double Sign(double value)
{
if(value > 0) return( 1);
if(value < 0) return(-1);
return(0);
}
double DeltaPhase[], aPrice[4], smooth[3], cycle[7], Q1[2], I1[2], iPeriod[2], cPeriod[4];
datetime prevcptime;
double cyclePeriod(double& price[],double alpha,int median,int dcsmooth,int bar)
{
double DC, MedianDelta = 0;
if(ArraySize(DeltaPhase) != Bars)
{
ArraySetAsSeries(DeltaPhase,false);
ArrayResize(DeltaPhase,Bars);
ArraySetAsSeries(DeltaPhase,true);
}
if(prevcptime != Time[bar])
{
for(int i=6;i>=1;i--)
{
cycle = cycle[i-1];
if(i < 4)
{
aPrice = aPrice[i-1];
cPeriod = cPeriod[i-1];
}
if(i < 3) smooth = smooth[i-1];
}
I1[1] = I1[0];
Q1[1] = Q1[0];
iPeriod[1] = iPeriod[0];
prevcptime = Time[bar];
}
aPrice[0] = price[bar];
if(bar < Bars - 3) smooth[0] = (aPrice[0] + 2*aPrice[1] + 2*aPrice[2] + aPrice[3])/6;
cycle[0] = (1 - 0.5*alpha)*(1 - 0.5*alpha)*(smooth[0] - 2*smooth[1] + smooth[2]) + 2*(1-alpha)*cycle[1] - (1-alpha)*(1-alpha)*cycle[2];
if(bar > Bars - 7) cycle[0] = (aPrice[0] - 2*aPrice[1] + aPrice[2])/4;
Q1[0] = (0.0962*cycle[0] + 0.5769*cycle[2] - 0.5769*cycle[4] - 0.0962*cycle[6])*(0.5 + 0.08*iPeriod[1]);
I1[0] = cycle[3];
if(bar < Bars- median)
{
if(Q1[0] != 0 && Q1[1] != 0) DeltaPhase[bar] = (I1[0]/Q1[0] - I1[1]/Q1[1])/(1 + I1[0]*I1[1]/(Q1[0]*Q1[1]));
if(DeltaPhase[bar] < 0.1) DeltaPhase[bar] = 0.1;
if(DeltaPhase[bar] > 1.1) DeltaPhase[bar] = 1.1;
MedianDelta = MedianOnArray(DeltaPhase,median,bar);
if(MedianDelta == 0) DC = 15; else DC = 6.28318/MedianDelta + 0.5;
iPeriod[0] = 0.33*DC + (1 - 2.0/(dcsmooth + 1))*iPeriod[1];
cPeriod[0] = 0.15*iPeriod[0] + 0.85*cPeriod[1];
}
if(cPeriod[3] == 0) return(0);
return(cPeriod[0]);
}
double MedianOnArray(double& price[],int per,int bar)
{
double median, array[];
ArrayResize(array,per);
for(int i=0;i<per;i++) array = price[bar+i];
ArraySort(array,WHOLE_ARRAY,0,MODE_DESCEND);
int num = (int)MathRound((per - 1)*0.5);
if(MathMod(per,2) > 0) median = array[num]; else median = 0.5*(array[num] + array[num+1]);
return(median);
}
// HeikenAshi Price
double haClose[2][2], haOpen[2][2], haHigh[2][2], haLow[2][2];
datetime prevhatime[2];
double HeikenAshi(int index,int price,int bar)
{
if(prevhatime[index] != Time[bar])
{
haClose[index][1] = haClose[index][0];
haOpen [index][1] = haOpen [index][0];
haHigh [index][1] = haHigh [index][0];
haLow [index][1] = haLow [index][0];
prevhatime[index] = Time[bar];
}
if(bar == Bars - 1)
{
haClose[index][0] = Close[bar];
haOpen [index][0] = Open [bar];
haHigh [index][0] = High [bar];
haLow [index][0] = Low [bar];
}
else
{
haClose[index][0] = (Open[bar] + High[bar] + Low[bar] + Close[bar])/4;
haOpen [index][0] = (haOpen[index][1] + haClose[index][1])/2;
haHigh [index][0] = MathMax(High[bar],MathMax(haOpen[index][0],haClose[index][0]));
haLow [index][0] = MathMin(Low [bar],MathMin(haOpen[index][0],haClose[index][0]));
}
switch(price)
{
case 0: return(haClose[index][0]); break;
case 1: return(haOpen [index][0]); break;
case 2: return(haHigh [index][0]); break;
case 3: return(haLow [index][0]); break;
case 4: return((haHigh[index][0] + haLow[index][0])/2); break;
case 5: return((haHigh[index][0] + haLow[index][0] + haClose[index][0])/3); break;
case 6: return((haHigh[index][0] + haLow[index][0] + 2*haClose[index][0])/4); break;
default: return(haClose[index][0]); break;
}
}
string tf(int itimeframe)
{
string result = "";
switch(itimeframe)
{
case PERIOD_M1: result = "M1" ;
case PERIOD_M5: result = "M5" ;
case PERIOD_M15: result = "M15";
case PERIOD_M30: result = "M30";
case PERIOD_H1: result = "H1" ;
case PERIOD_H4: result = "H4" ;
case PERIOD_D1: result = "D1" ;
case PERIOD_W1: result = "W1" ;
case PERIOD_MN1: result = "MN1";
default: result = "N/A";
}
if(result == "N/A")
{
if(itimeframe < PERIOD_H1 ) result = "M" + (string)itimeframe;
if(itimeframe >= PERIOD_H1 ) result = "H" + (string)(itimeframe/PERIOD_H1);
if(itimeframe >= PERIOD_D1 ) result = "D" + (string)(itimeframe/PERIOD_D1);
if(itimeframe >= PERIOD_W1 ) result = "W" + (string)(itimeframe/PERIOD_W1);
if(itimeframe >= PERIOD_MN1) result = "MN" + (string)(itimeframe/PERIOD_MN1);
}
return(result);
}
|