#property copyright "Extreme TMA System"
#property link "http://www.forexfactory.com/showthread.php?t=343533m"
#property indicator_chart_window
extern color NeutralColor = LightGray;
extern color BullColor = SeaGreen;
extern color ExtremeBullColor = Lime;
extern color BearColor = Orange;
extern color ExtremeBearColor = Red;
extern int TmaPeriod = 56;
extern int TmaAtrPeriod = 100;
extern double TmaBandSize = 2;
extern double TmaSlopeThreshold = 0.5;
extern double TmaBandSizeH1 = 3;
extern double TmaBandSizeH4 = 3;
extern int PivotHoursShift = 0;
extern double PivotThreshold = 10;
extern int MaPeriod = 10;
//This is the same as 4 in the original TMA MACross
extern int MaShift = 1;
extern int Size = 13;
extern string Font = "Arial";
extern bool ShowPrice = false;
extern bool ShowDailyAtr = true;
extern bool ShowSpread = true;
extern bool ShowTmaSize = true;
extern bool ShowTmaSizeH1 = true;
extern bool ShowTmaSizeH4 = true;
extern bool ShowSlope = true;
extern bool ShowSlopeH1 = true;
extern bool ShowSlopeH4 = true;
extern bool ShowExtremeTMA = true;
extern bool ShowSlopeChange = true;
extern bool ShowPivotDistance = true;
extern bool ShowHeikenAshi = true;
extern bool ShowMACrossover = false;
extern bool AlertOn = false;
extern bool AlertMessage = true;
extern bool AlertEmail = false;
extern bool AlertSound = true;
extern string AlertSoundFile = "alert2.wav";
int LinearRegressionPeriod = 7;
bool ShowLinearPriceChange = false;
int Bottom = 25;
double Tick = 0;
bool AdditionalDigit;
double Pivots[];
int LastPivotDay= 0;
bool AlertHappened = false;
//+------------------------------------------------------------------+
// expert initialization function |
//+------------------------------------------------------------------+
int init()
{
ArrayResize(Pivots,11);
Tick = MarketInfo(Symbol(), MODE_TICKSIZE);
AdditionalDigit = MarketInfo(Symbol(), MODE_MARGINCALCMODE) == 0 && MarketInfo(Symbol(), MODE_PROFITCALCMODE) == 0 && Digits % 2 == 1;
if (AdditionalDigit) {
Tick *= 10;
}
initGraph();
return(0);
}
int deinit()
{
deinitGraph();
Print("shutdown error - ",GetLastError());
return(0);
}
int start()
{
main();
return(0);
}
void main()
{
RefreshRates();
//General Info
double spread=NormalizeDouble(((Ask-Bid)/Point)/10,1);
int dayShift = iBarShift(Symbol(),PERIOD_D1,Time[0]);
double atr = iATR(Symbol(),PERIOD_D1, 14,dayShift);
double price = NormalizeDouble(Close[0],4);
atr = NormalizeDouble((atr/Point)/10,1);
if (ShowSpread) paintGeneral("SpreadValue", spread, NeutralColor, 1);
if (ShowDailyAtr) paintGeneral("AtrValue", atr, NeutralColor);
if (ShowPrice) paintPrice(price);
double tmaH1,tmaH1Prev,tmaH4,tmaH4Prev;
//Tma Info
GetPivots(Symbol());
int shiftH1 = iBarShift(NULL,60,Time[0]);
int shiftH4 = iBarShift(Symbol(),240,Time[0]);
if (ShowSlopeH1)
{
tmaH1 = CalcTma(60, shiftH1);
tmaH1Prev = CalcTma(60, shiftH1+1);
}
if (ShowSlopeH4)
{
tmaH4 = CalcTma(240, shiftH4);
tmaH4Prev = CalcTma(240, shiftH4+1);
}
//if (Symbol() == "EURUSDm") Print (" tmaH1 ",tmaH1," tmaH1Prev ",tmaH1Prev, " shiftH1 ", shiftH1, " Time[0] ", TimeToStr(Time[0])
//, "iClose(Symbol(),60,shiftH1);", iClose(Symbol(),60,shiftH1), "iTime(Symbol(),60,shiftH1);", TimeToStr(iTime(Symbol(),60,shiftH1)));
double tma = getTma(Symbol(),0, 0);
double tmaPrev = getTma(Symbol(),0, 1);
double tmaPrev2 = getTma(Symbol(),0, 2);
double tmaPrev3 = getTma(Symbol(),0, 3);
double priceSlope = getPriceSlope(Symbol(),0,LinearRegressionPeriod);
double pivotDist = GetNearestPivotDistance()/Tick;
double tmaAtr = iATR( Symbol(), 0, TmaAtrPeriod, 10);
double tmaAtrH1 = iATR( Symbol(), 60, TmaAtrPeriod,shiftH1 + 10);
double tmaAtrH4 = iATR( Symbol(), 240, TmaAtrPeriod, shiftH4 + 10);
double diff = Close[0] - tma;
double extremeTma = (diff/tmaAtr) / TmaBandSize;
double n = tmaAtr * 0.1;
double tmaSlope = ((tma- tmaPrev) / n) ;
double tmaSlopeH1 = ((tmaH1- tmaH1Prev) / (tmaAtrH1 * 0.1)) ;
double tmaSlopeH4 = ((tmaH4- tmaH4Prev) / (tmaAtrH4 * 0.1)) ;
double tmaSlope1 = ((tmaPrev- tmaPrev2) / n) ;
double tmaSlope2 = ((tmaPrev2- tmaPrev3) / n) ;
double tmaSlopeChange = ((tmaSlope - tmaSlope1) + (tmaSlope1 - tmaSlope2)) / 2.0;
if (ShowTmaSize) paintGeneral("TmaSizeValue", (tmaAtr/Tick) * 2 * TmaBandSize , NeutralColor);
if (ShowTmaSizeH1) paintGeneral("TmaSizeH1Value", (tmaAtrH1/Tick) * 2 * TmaBandSizeH1 , NeutralColor);
if (ShowTmaSizeH4) paintGeneral("TmaSizeH4Value", (tmaAtrH4/Tick) * 2 * TmaBandSizeH4 , NeutralColor);
color c = NeutralColor;
if (ShowExtremeTMA)
{
if(extremeTma<=-1){c = ExtremeBullColor; }
else if(extremeTma>=1){c = ExtremeBearColor; }
else if(extremeTma>0){c = BearColor; }
else if(extremeTma<0){c = BullColor; }
else {c = NeutralColor; }
paintGeneral("ExtremeTMA", extremeTma, c);
}
if (ShowSlope)
{
if(tmaSlope<-1 * TmaSlopeThreshold){c = ExtremeBearColor; }
else if(tmaSlope>TmaSlopeThreshold){c = ExtremeBullColor; }
//else {c = NeutralColor; }
paintGeneral("TmaSlope", tmaSlope, c,2);
}
if (ShowSlopeH1)
{
if(tmaSlopeH1 <-1 * TmaSlopeThreshold){c = ExtremeBearColor; }
else if(tmaSlopeH1 >TmaSlopeThreshold){c = ExtremeBullColor; }
else if(tmaSlopeH1 > 0){c = BullColor; }
else if(tmaSlopeH1 < 0 ){c = BearColor; }
else {c = NeutralColor; }
paintGeneral("TmaSlopeH1", tmaSlopeH1, c,2);
}
if (ShowSlopeH4)
{
if(tmaSlopeH4 <-1 * TmaSlopeThreshold){c = ExtremeBearColor; }
else if(tmaSlopeH4 >TmaSlopeThreshold){c = ExtremeBullColor; }
else if(tmaSlopeH4 > 0){c = BullColor; }
else if(tmaSlopeH4 < 0 ){c = BearColor; }
else {c = NeutralColor; }
paintGeneral("TmaSlopeH4", tmaSlopeH4, c,2);
}
if (ShowSlopeChange)
{
if(tmaSlopeChange<0 && extremeTma>= 1){c = ExtremeBearColor; }
else if(tmaSlopeChange<0){c = BearColor; }
else if(tmaSlopeChange>0 && extremeTma<= -1){c = ExtremeBullColor; }
else if(tmaSlopeChange>0){c = BullColor; }
else {c = NeutralColor; }
paintGeneral("TmaSlopeChange", tmaSlopeChange* 100, c);
}
if(ShowLinearPriceChange)
{
if(priceSlope<0 && tmaSlopeChange>0){c = ExtremeBullColor; }
else if(priceSlope>0 && tmaSlopeChange<0){c = ExtremeBearColor; }
else {c = NeutralColor; }
paintGeneral("PriceSlope", priceSlope, c);
}
if(ShowPivotDistance)
{
if(pivotDist>0 && pivotDist < PivotThreshold){c = ExtremeBullColor; }
else if (pivotDist>0){c = BullColor; }
else if(pivotDist<0 && MathAbs(pivotDist) < PivotThreshold){c = ExtremeBearColor; }
else if(pivotDist<0){c = BearColor; }
//else if(extremeTma>0){c = BearColor; }
//else if(extremeTma<0){c = BullColor; }
else {c = NeutralColor; }
paintGeneral("PivotDistance", pivotDist, c);
}
if(ShowHeikenAshi)
{
double ha = (GetHAClose(0) - GetHAOpen(0))/Tick;
if(ha > 0 && extremeTma<=-1){c = ExtremeBullColor; }
else if(ha<0 && extremeTma>=1){c = ExtremeBearColor; }
else if(ha>0){c = BullColor; }
else if(ha<0 ){c = BearColor; }
else {c = NeutralColor; }
paintGeneral("HeikenAshi", ha, c);
}
if(ShowMACrossover)
{
double back = getMaBack(Symbol(),0);
double front = getMaFront(Symbol(),0);
double maCrossover = back-front;
if(maCrossover > 0 && extremeTma<=1){c = ExtremeBullColor; }
else if(maCrossover<0 && extremeTma<=-1){c = ExtremeBearColor; }
else if(maCrossover>0){c = BullColor; }
else if(maCrossover<0 ){c = BearColor; }
else {c = NeutralColor; }
paintGeneral("MaCrossover", maCrossover/Tick, c);
}
if (AlertOn)
{
if(extremeTma <= -1 && tmaSlope > -1 * TmaSlopeThreshold && tmaSlopeChange > 0 && MathAbs(pivotDist) < PivotThreshold)
{
Print("ALERT BUY");
if(!AlertHappened)
{
string message = StringConcatenate(Symbol()," Extreme TMA Buy");
if (AlertMessage) Alert(message);
if (AlertEmail) SendMail(message,message);
if (AlertSound) PlaySound(AlertSoundFile);
AlertHappened = true;
}
}
else if(extremeTma >= 1 && tmaSlope < TmaSlopeThreshold && tmaSlopeChange < 0 && MathAbs(pivotDist) < PivotThreshold)
{
Print("ALERT SELL");
if(!AlertHappened)
{
message = StringConcatenate(Symbol()," Extreme TMA Sell");
if (AlertMessage) Alert(message);
if (AlertEmail) SendMail(message,message);
if (AlertSound) PlaySound(AlertSoundFile);
AlertHappened = true;
}
}
else
{
AlertHappened = false;
}
}
}
//Data Retrieval
double getMaBack(string symbol, int timeFrame)
{
int backIdx = MaShift - MaPeriod;
//double back = iCustom(symbol,timeFrame,"Ma_Crossover_Lines",MaPeriod,MaShift,0,0);
double back = iMA( symbol, timeFrame, MaPeriod + backIdx, 0, MODE_LWMA, PRICE_TYPICAL, 0);
return (back);
}
double getMaFront(string symbol, int timeFrame)
{
double front = iMA( symbol, timeFrame, MaPeriod, 0, MODE_LWMA, PRICE_TYPICAL, MaShift);
return (front);
}
double getPriceSlope(string symbol, int timeFrame,int Length)
{
double SumBars = Length * (Length - 1) * 0.5;
double SumSqrBars = (Length - 1.0) * Length * (2.0 * Length - 1.0) / 6.0;
double slope;
int i=0;
double Sum1 = 0;
for(i=0;i<=Length-1;i++) Sum1 += i*iMA(NULL,0,1,0,1,PRICE_CLOSE,i);
double SumY = 0;
for(i=0;i<=Length-1;i++) SumY += iMA(NULL,0,1,0,1,PRICE_CLOSE,i);
double Sum2 = SumBars * SumY;
double Num1 = Length * Sum1 - Sum2;
double Num2 = SumBars * SumBars - Length * SumSqrBars;
if( Num2 != 0 )
slope = 10000*Num1/Num2;
else
slope = 0;
if (StringSubstr(Symbol(),3,3) == "JPY") slope = slope / 100;
return (slope);
}
double CalcTma(int timeFrame, int inx)
{
double dblSum = (TmaPeriod+1)*iClose(Symbol(),timeFrame,inx);
double dblSumw = (TmaPeriod+1);
int jnx, knx;
for ( jnx = 1, knx = TmaPeriod; jnx <= TmaPeriod; jnx++, knx-- )
{
dblSum += ( knx * iClose(Symbol(),timeFrame,inx+jnx) );
dblSumw += knx;
if ( jnx <= inx )
{
if (iTime(Symbol(),timeFrame,inx-jnx) > Time[0])
{
//Print (" TimeFrameValue ", TimeFrameValue , " inx ", inx," jnx ", jnx, " iTime(Symbol(),TimeFrameValue,inx-jnx) ", TimeToStr(iTime(Symbol(),TimeFrameValue,inx-jnx)), " Time[0] ", TimeToStr(Time[0]));
continue;
}
dblSum += ( knx * iClose(Symbol(),timeFrame,inx-jnx) );
dblSumw += knx;
}
}
return( dblSum / dblSumw );
}
double getTma(string symbol, int timeFrame, int index)
{
double dblSum = (TmaPeriod+1)*iClose(symbol, timeFrame,index);
double dblSumw = (TmaPeriod+1);
int jnx, knx;
for ( jnx = 1, knx = TmaPeriod; jnx <= TmaPeriod; jnx++, knx-- )
{
dblSum += ( knx * iClose(symbol, timeFrame,index+jnx) );
dblSumw += knx;
if ( jnx <= index )
{
dblSum += ( knx * iClose(symbol, timeFrame,index-jnx) );
dblSumw += knx;
}
}
return( dblSum / dblSumw );
}
// Start Pivot Code
double GetNearestPivotDistance()
{
int index = 0;
double minDistance = 999999;
for(int i=0; i < ArraySize(Pivots);i++)
{
if(MathAbs(Close[0]-Pivots[i]) < minDistance)
{
minDistance = MathAbs(Close[0]-Pivots[i]);
index = i;
}
}
double distance = Close[0]-Pivots[index];
return (distance);
}
void GetPivots(string symbol)
{
double prices[4];
datetime start = GetDayStart(Time[0]);
if(LastPivotDay == start) return;
GetPrevDayPrices(prices,start);
double range = prices[PRICE_HIGH]-prices[PRICE_LOW];
Pivots[0]=NormalizeDouble((prices[PRICE_HIGH]+prices[PRICE_LOW]+ prices[PRICE_CLOSE] )/3.0,Digits);
Pivots[1] = Pivots[0] - (0.382 * range);
Pivots[2] = Pivots[0] - (0.618033 * range);
Pivots[3] = Pivots[0] - (1 * range);
Pivots[4] = Pivots[0] - (1.618033 * range);
Pivots[5] = Pivots[0] - (2.618033 * range);
Pivots[6] = Pivots[0] + (0.382 * range);
Pivots[7] = Pivots[0] + (0.618033 * range);
Pivots[8] = Pivots[0] + (1 * range);
Pivots[9] = Pivots[0] + (1.618033 * range);
Pivots[10] = Pivots[0] + (2.618033 * range);
LastPivotDay = start;
//----
}
datetime GetDayStart(datetime timestamp) {
// Shift to start of effective day (could be Sat/Sun)
timestamp -= PivotHoursShift * 3600;
timestamp -= MathMod(timestamp, 86400);
// Move weekend to Monday start
if (TimeDayOfWeek(timestamp) == 0) {
timestamp += 24 * 3600;
}
else if(TimeDayOfWeek(timestamp) == 6) {
timestamp += 48 * 3600;
}
// Shift back to 5PM EST
timestamp += PivotHoursShift * 3600;
return(timestamp);
}
void GetPrevDayPrices(double& prices[], datetime timestamp) {
// Get the last bar of the previous trading day
int numHoursShift = 1; // one hour back in most cases.
// however if it's Weekly open, need to go back 49 hours.
if (TimeDayOfWeek(timestamp - PivotHoursShift * 3600)==1) {
numHoursShift = 48;
}
// since iBarShift exact param = false, the previous existing bar will be returned
int iBarIndex = iBarShift(NULL,PERIOD_H1,timestamp - numHoursShift*3600,false);
datetime dtPrevDayStart = GetDayStart(iTime(NULL,PERIOD_H1,iBarIndex));
// Get close price for the day and set initial values for high and low
prices[PRICE_HIGH] = 0; prices[PRICE_LOW] = 9999; prices[PRICE_OPEN] = 0;
prices[PRICE_CLOSE] = iClose(NULL,PERIOD_H1,iBarIndex-1);
// Iterate back and check for high/low prices until all of previous trading day covered
while (GetDayStart(iTime(NULL,PERIOD_H1,iBarIndex)) == dtPrevDayStart) {
prices[PRICE_HIGH] = MathMax(prices[PRICE_HIGH], iHigh (NULL,PERIOD_H1,iBarIndex));
prices[PRICE_LOW] = MathMin(prices[PRICE_LOW], iLow (NULL,PERIOD_H1,iBarIndex));
prices[PRICE_OPEN] = iOpen(NULL,PERIOD_H1,iBarIndex);
iBarIndex++;
}
return;
}
// End Pivot Code
//End Data Retrieval
//Drawing
void paintPrice(double value)
{
int precision = 4;
if (StringSubstr(Symbol(),3,3) == "JPY") precision = 2;
ObjectSetText("ExtremeTmaInfo_PriceValue",DoubleToStr(value,precision),Size,Font,NeutralColor);
}
void paintGeneral(string name, double value, color c, int precision = 1)
{
ObjectSetText("ExtremeTmaInfo_" + name,DoubleToStr(value,precision),Size,Font,c);
}
//----------------------------------------
void initGraph()
{
int bottom = Bottom;
if(ShowMACrossover)
{
objectCreate("ExtremeTmaInfo_MaCrossover",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_MaCrossoverLabel",65,bottom,"Ma Crossover:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if(ShowHeikenAshi)
{
objectCreate("ExtremeTmaInfo_HeikenAshi",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_HeikenAshiLabel",65,bottom,"Heiken Ashi:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowPivotDistance)
{
objectCreate("ExtremeTmaInfo_PivotDistance",12,bottom,"9",Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_PivotDistanceLabel",65,bottom,"Pivot Distance:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowLinearPriceChange)
{
objectCreate("ExtremeTmaInfo_PriceSlope",12,bottom,"9",Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_PriceSlopeLabel",65,bottom,"Price Change:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if(ShowSlopeChange)
{
objectCreate("ExtremeTmaInfo_TmaSlopeChange",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSlopeChangeLabel",65,bottom,"Slope Change:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowExtremeTMA)
{
objectCreate("ExtremeTmaInfo_ExtremeTMA",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_ExtremeTMALabel",65,bottom,"Extreme TMA:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowSlopeH4)
{
objectCreate("ExtremeTmaInfo_TmaSlopeH4",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSlopeH4Label",65,bottom,"TMA Slope (H4):",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowSlopeH1)
{
objectCreate("ExtremeTmaInfo_TmaSlopeH1",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSlopeH1Label",65,bottom,"TMA Slope (H1):",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowSlope)
{
objectCreate("ExtremeTmaInfo_TmaSlope",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSlopeLabel",65,bottom,"TMA Slope:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowTmaSizeH4)
{
objectCreate("ExtremeTmaInfo_TmaSizeH4Value",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSizeH4Label",65,bottom,"TMA Size (H4):",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowTmaSizeH1)
{
objectCreate("ExtremeTmaInfo_TmaSizeH1Value",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSizeH1Label",65,bottom,"TMA Size (H1):",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowTmaSize)
{
objectCreate("ExtremeTmaInfo_TmaSizeValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_TmaSizeLabel",65,bottom,"TMA Size:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowSpread)
{
objectCreate("ExtremeTmaInfo_SpreadValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_SpreadValueLabel",65,bottom,"Spread:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowDailyAtr)
{
objectCreate("ExtremeTmaInfo_AtrValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_AtrValueLabel",65,bottom,"Atr(14-day):",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
if (ShowPrice)
{
objectCreate("ExtremeTmaInfo_PriceValue",12,bottom,DoubleToStr(9,1),Size,Font,NeutralColor);
objectCreate("ExtremeTmaInfo_PriceValueLabel",65,bottom,"Price:",Size,Font,NeutralColor);
bottom = bottom + (Size * 1.6);
}
WindowRedraw();
}
//----------------------------------------
void deinitGraph()
{
DeleteObjectsByPrefix("ExtremeTmaInfo_");
DeleteObjectsByPrefix("ParadoxInfo_");
WindowRedraw();
}
//+------------------------------------------------------------------+
void objectCreate(string name,int x,int y,string text="-",int size=42,
string font="Arial",color colour=CLR_NONE)
{
ObjectCreate(name,OBJ_LABEL,0,0,0);
ObjectSet(name,OBJPROP_CORNER,3);
ObjectSet(name,OBJPROP_COLOR,colour);
ObjectSet(name,OBJPROP_XDISTANCE,x);
ObjectSet(name,OBJPROP_YDISTANCE,y);
ObjectSetText(name,text,size,font,colour);
}
void DeleteObjectsByPrefix(string Prefix)
{
int L = StringLen(Prefix);
int i = 0;
while(i < ObjectsTotal())
{
string ObjName = ObjectName(i);
if(StringSubstr(ObjName, 0, L) != Prefix)
{
i++;
continue;
}
ObjectDelete(ObjName);
}
}
//End Drawing
double GetHAClose(int index)
{
return((Open[index]+High[index]+Low[index]+Close[index])/4);
}
double GetHAOpen(int index)
{
//The higher you make this lookback the lower the error with the true Heiken Ashi Open)
int lookback = 8;
double open = GetHAClose(index+lookback);
lookback--;
for(int j = index + lookback;j > index;j--)
{
open = (open + GetHAClose(j)) / 2;
}
return (open);
}