Code: Select all
//+------------------------------------------------------------------+
//| |
//| disclaimer : centered triangular moving average |
//| recalculates last half cycle bars, and thus those |
//| bars are subject of changing |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_width1 0
#property indicator_width2 0
//
//
//
//
//
extern string TimeFrame = "Current time frame";
extern int T3Period = 10;
extern int T3Price = PRICE_CLOSE;
extern double T3Hot = 0.618;
extern bool T3Original = false;
extern int TMAHalfCycle = 5;
extern int TMAPrice = PRICE_CLOSE;
extern int DeltaForSell = 0;
extern int DeltaForBuy = 0;
extern bool alertsOn = false;
extern bool alertsOnCurrent = true;
extern bool alertsMessage = true;
extern bool alertsSound = true;
extern bool alertsEmail = false;
extern string soundfile = "alert2.wav";
//
//
//
//
//
double UpBuffer[];
double DnBuffer[];
double trend[];
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
int init()
{
IndicatorBuffers(3);
SetIndexBuffer(0,UpBuffer); SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,233); SetIndexLabel(0,"Up Signal");
SetIndexBuffer(1,DnBuffer); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,234); SetIndexLabel(1,"Down Signal");
SetIndexBuffer(2,trend);
return(0);
}
int deinit() { return(0); }
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
int start()
{
int i,j,k,counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=MathMax(MathMin(Bars-counted_bars,Bars-1),2*TMAHalfCycle);
//
//
//
//
//
for (i=limit; i>=0; i--)
{
double sum = (TMAHalfCycle+1)*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i);
double sumw = (TMAHalfCycle+1);
for(j=1, k=TMAHalfCycle; j<=TMAHalfCycle; j++, k--)
{
sum += k*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i+j);
sumw += k;
if (j<=i)
{
sum += k*iMA(NULL,0,1,0,MODE_SMA,TMAPrice,i-j);
sumw += k;
}
}
double tma = sum/sumw;
double t3 = iT3(iMA(NULL,0,1,0,MODE_SMA,T3Price,i),T3Period,T3Hot,T3Original,i);
//
//
//
//
//
DnBuffer[i] = EMPTY_VALUE;
UpBuffer[i] = EMPTY_VALUE;
trend[i] = trend[i+1];
if (t3<tma) trend[i] = 1;
if (t3>tma) trend[i] = -1;
if (trend[i]!= trend[i+1])
if (trend[i] == 1)
UpBuffer[i] = Low[i] -iATR(NULL,0,20,i)/2.0;
else DnBuffer[i] = High[i]+iATR(NULL,0,20,i)/2.0;
if( tma > (t3 +(DeltaForBuy*Point)) && tma <= t3)
else if( t3 >= t3 && tma < (t3 - (DeltaForSell*Point)))
{
//
//
//
//
//
if (alertsOn)
{
if (alertsOnCurrent)
int whichBar = 0;
else whichBar = 1;
if (trend[whichBar] != trend[whichBar+1])
if (trend[whichBar] == 1)
doAlert("up");
else doAlert("down");
}
return(0);
}
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
//+------------------------------------------------------------------+
void doAlert(string doWhat)
{
static string previousAlert="nothing";
static datetime previousTime;
string message;
if (previousAlert != doWhat || previousTime != Time[0]) {
previousAlert = doWhat;
previousTime = Time[0];
//
//
//
//
//
message = StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," uni cross ",doWhat);
if (alertsMessage) Alert(message);
if (alertsEmail) SendMail(StringConcatenate(Symbol()," uni cross "),message);
if (alertsSound) PlaySound(soundfile);
}
}
//------------------------------------------------------------------
//
//------------------------------------------------------------------
//
//
//
//
//
double workT3[][6];
double workT3Coeffs[][6];
#define _period 0
#define _c1 1
#define _c2 2
#define _c3 3
#define _c4 4
#define _alpha 5
//
//
//
//
//
double iT3(double price, double period, double hot, bool original, int i, int instanceNo=0)
{
if (ArrayRange(workT3,0) != Bars) ArrayResize(workT3,Bars);
if (ArrayRange(workT3Coeffs,0) < (instanceNo+1)) ArrayResize(workT3Coeffs,instanceNo+1);
if (workT3Coeffs[instanceNo][_period] != period)
{
workT3Coeffs[instanceNo][_period] = period;
double a = hot;
workT3Coeffs[instanceNo][_c1] = -a*a*a;
workT3Coeffs[instanceNo][_c2] = 3*a*a+3*a*a*a;
workT3Coeffs[instanceNo][_c3] = -6*a*a-3*a-3*a*a*a;
workT3Coeffs[instanceNo][_c4] = 1+3*a+a*a*a+3*a*a;
if (original)
workT3Coeffs[instanceNo][_alpha] = 2.0/(1.0 + period);
else workT3Coeffs[instanceNo][_alpha] = 2.0/(2.0 + (period-1.0)/2.0);
}
//
//
//
//
//
int buffer = instanceNo*6;
int r = Bars-i-1;
if (r == 0)
{
workT3[r][0+buffer] = price;
workT3[r][1+buffer] = price;
workT3[r][2+buffer] = price;
workT3[r][3+buffer] = price;
workT3[r][4+buffer] = price;
workT3[r][5+buffer] = price;
}
else
{
workT3[r][0+buffer] = workT3[r-1][0+buffer]+workT3Coeffs[instanceNo][_alpha]*(price -workT3[r-1][0+buffer]);
workT3[r][1+buffer] = workT3[r-1][1+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][0+buffer]-workT3[r-1][1+buffer]);
workT3[r][2+buffer] = workT3[r-1][2+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][1+buffer]-workT3[r-1][2+buffer]);
workT3[r][3+buffer] = workT3[r-1][3+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][2+buffer]-workT3[r-1][3+buffer]);
workT3[r][4+buffer] = workT3[r-1][4+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][3+buffer]-workT3[r-1][4+buffer]);
workT3[r][5+buffer] = workT3[r-1][5+buffer]+workT3Coeffs[instanceNo][_alpha]*(workT3[r][4+buffer]-workT3[r-1][5+buffer]);
}
//
//
//
//
//
return(workT3Coeffs[instanceNo][_c1]*workT3[r][5+buffer] +
workT3Coeffs[instanceNo][_c2]*workT3[r][4+buffer] +
workT3Coeffs[instanceNo][_c3]*workT3[r][3+buffer] +
workT3Coeffs[instanceNo][_c4]*workT3[r][2+buffer]);
}