lowPass filter

Dewey McG
Trader
Posts: 435
Joined: Sat Nov 26, 2011 4:20 pm
Location: Tampa FL

lowPass filter

Post by Dewey McG »

Can anyone code one for Empty4? I have the Zorro version:

var smoothF(int period) { return 2./(period+1); }

var LowPass(var *Data,int Period)
{
var* LP = series(*Data,3);
var a = smoothF(Period);
var a2 = a*a;
return LP[0] = (a-0.25*a2)*Data[0]
+ 0.5*a2*Data[1]
- (a-0.75*a2)*Data[2]
+ 2*(1.-a)*LP[1]
- (1.-a)*(1.-a)*LP[2];
}


As a complete beginner I don't have a clue how to convert this into one for Empty4.
garyfritz

Re: lowPass filter

Post by garyfritz »

You have to apply this to a series (like a price series or a buffer in an indicator) so you have history to work on. It uses the 3 most recent values of Data.

However it also uses the last two values of the LowPass function.

So let's say you're applying this to the daily Close values. It uses the Close from today, yesterday, and two days ago, AND it uses the LowPass values from yesterday and two days ago. (And of course yesterday's LowPass uses the LowPass from the two previous days, and 2-days-ago LowPass uses the LowPass from the two days before that, and...)

So I don't think you can define this as a simple function. You have to compute the whole series in order. You'd have to keep or calculate a series (history) of the previous LowPass values.

This is fairly straightforward in an EA, because they execute from oldest to newest in linear order. Indicators don't, which makes it challenging. There are ways to do this in an indicator but they're messy. I'll let somebody else take a shot at it. If nobody volunteers I'll try to get to it later this week.
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: lowPass filter

Post by gaheitman »

Dewey McG wrote:Can anyone code one for Empty4? I have the Zorro version:

var smoothF(int period) { return 2./(period+1); }

var LowPass(var *Data,int Period)
{
var* LP = series(*Data,3);
var a = smoothF(Period);
var a2 = a*a;
return LP[0] = (a-0.25*a2)*Data[0]
+ 0.5*a2*Data[1]
- (a-0.75*a2)*Data[2]
+ 2*(1.-a)*LP[1]
- (1.-a)*(1.-a)*LP[2];
}


As a complete beginner I don't have a clue how to convert this into one for Empty4.
I'm not sure what the lowpass should look like, but I believe this is a faithful representation of the formula you use above. I'm sure Gary will give it a once over, right Gary? ;)

The pertinent loop:

Code: Select all

   double a = 2.0/(Per+1.0);
   double a2 = a*a;

   for(i=limit; i>=0; i--) {


      LP[i] = (a-0.25*a2)*Close[i]
               + 0.5*a2*Close[i+1]
               - (a-0.75*a2)*Close[i+2]
               + 2*(1.0-a)*LP[i+1]
               - (1.0-a)*(1.0-a)*LP[i+2];
   }   
EDIT: Indicator update here: http://www.stevehopwoodforex.com/phpBB3 ... 502#p28502
George
dietcoke
Trader
Posts: 162
Joined: Tue Nov 15, 2011 9:59 pm

Re: lowPass filter

Post by dietcoke »

gaheitman wrote:
Dewey McG wrote:Can anyone code one for Empty4? I have the Zorro version:

var smoothF(int period) { return 2./(period+1); }

var LowPass(var *Data,int Period)
{
var* LP = series(*Data,3);
var a = smoothF(Period);
var a2 = a*a;
return LP[0] = (a-0.25*a2)*Data[0]
+ 0.5*a2*Data[1]
- (a-0.75*a2)*Data[2]
+ 2*(1.-a)*LP[1]
- (1.-a)*(1.-a)*LP[2];
}


As a complete beginner I don't have a clue how to convert this into one for Empty4.
I'm not sure what the lowpass should look like, but I believe this is a faithful representation of the formula you use above. I'm sure Gary will give it a once over, right Gary? ;)

The pertinent loop:

Code: Select all

   double a = 2.0/(Per+1.0);
   double a2 = a*a;

   for(i=limit; i>=0; i--) {


      LP[i] = (a-0.25*a2)*Close[i]
               + 0.5*a2*Close[i+1]
               - (a-0.75*a2)*Close[i+2]
               + 2*(1.0-a)*LP[i+1]
               - (1.0-a)*(1.0-a)*LP[i+2];
   }   
George

I thought this looked a bit familiar:

See MA method 12 in allaverages

Code: Select all

// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
double ITrend(double price[],double array[],int per,int bar)
{
   double alfa = 2.0/(per+1);
   if(bar > 7)
   double it = (alfa - alfa*alfa/4)*price[bar]+ 0.5*alfa*alfa*price[bar-1]-(alfa - 0.75*alfa*alfa)*price[bar-2]+
   2*(1-alfa)*array[bar-1] - (1-alfa)*(1-alfa)*array[bar-2];
   else
   it = (price[bar] + 2*price[bar-1]+ price[bar-2])/4;
Image
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: lowPass filter

Post by gaheitman »

dietcoke wrote:
gaheitman wrote:
I'm not sure what the lowpass should look like, but I believe this is a faithful representation of the formula you use above. I'm sure Gary will give it a once over, right Gary? ;)

The pertinent loop:

Code: Select all

   double a = 2.0/(Per+1.0);
   double a2 = a*a;

   for(i=limit; i>=0; i--) {


      LP[i] = (a-0.25*a2)*Close[i]
               + 0.5*a2*Close[i+1]
               - (a-0.75*a2)*Close[i+2]
               + 2*(1.0-a)*LP[i+1]
               - (1.0-a)*(1.0-a)*LP[i+2];
   }   
George

I thought this looked a bit familiar:

See MA method 12 in allaverages

Code: Select all

// MA_Method=12: ITrend - Instantaneous Trendline by J.Ehlers
double ITrend(double price[],double array[],int per,int bar)
{
   double alfa = 2.0/(per+1);
   if(bar > 7)
   double it = (alfa - alfa*alfa/4)*price[bar]+ 0.5*alfa*alfa*price[bar-1]-(alfa - 0.75*alfa*alfa)*price[bar-2]+
   2*(1-alfa)*array[bar-1] - (1-alfa)*(1-alfa)*array[bar-2];
   else
   it = (price[bar] + 2*price[bar-1]+ price[bar-2])/4;
Wow, you remembered that? Impressive. ;)

George
garyfritz

Re: lowPass filter

Post by garyfritz »

That IS impressive! :D

But Dewey, understand that Empty4 indicators and EAs have very different execution models (one of the LOVELY things I just LOVE about the Empty4 definition...) Code that works in an indicator probably won't work in an EA, which I assume is what you want. The whole init() / start() / etc stuff is indicator-only. In this case I believe you could drop the ITrend() function from AllAverages into an EA, and as long as you pass it a working array to hold LP (in the array[] parameter) it should work OK.

George and DC, I've got some questions about the AA code. I'm looking at the 2.5 version.

The AA version passes in the array[] parameter to hold the history held in LP in the original. But the candle loop counts from zero (or small) to larger -- counting BACKWARDS in time. How does it reference the earlier elements of array[] if it hasn't calculated them yet??

Empty4 shifts candles -- and buffer arrays -- as each new candle arrives. I thought you were supposed to handle that with ArraySetAsSeries(), telling Empty4 that an array (like the one passed in as array[]) should shift along with the display buffer? This code doesn't do that. How/why does that work?

The candle loop is "for(y=mcnt_bars;y<mBars;y++)". But mcnt_bars is never initialized unless cnt_bars<0. Apparently it just assumes it will get auto-initalized to zero? Sloppy.
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: lowPass filter

Post by gaheitman »

garyfritz wrote:That IS impressive! :D

But Dewey, understand that Empty4 indicators and EAs have very different execution models (one of the LOVELY things I just LOVE about the Empty4 definition...) Code that works in an indicator probably won't work in an EA, which I assume is what you want. The whole init() / start() / etc stuff is indicator-only. In this case I believe you could drop the ITrend() function from AllAverages into an EA, and as long as you pass it a working array to hold LP (in the array[] parameter) it should work OK.

George and DC, I've got some questions about the AA code. I'm looking at the 2.5 version.

The AA version passes in the array[] parameter to hold the history held in LP in the original. But the candle loop counts from zero (or small) to larger -- counting BACKWARDS in time. How does it reference the earlier elements of array[] if it hasn't calculated them yet??

Empty4 shifts candles -- and buffer arrays -- as each new candle arrives. I thought you were supposed to handle that with ArraySetAsSeries(), telling Empty4 that an array (like the one passed in as array[]) should shift along with the display buffer? This code doesn't do that. How/why does that work?

The candle loop is "for(y=mcnt_bars;y<mBars;y++)". But mcnt_bars is never initialized unless cnt_bars<0. Apparently it just assumes it will get auto-initalized to zero? Sloppy.
They actually never convert the arrays they use to series arrays, so the earliest bar is index zero in the array and the most recent is at ArraySize(). Iterating from 0 to Bars-1 is actually moving forward in time, so they have calculated the previous bar(s).

This line:

Code: Select all

      aPrice[y] = iMA(NULL,TimeFrame,1,MA_Shift,0,Price,mBars-y-1);   
does the array/series order switching, since when y=0, the shift for the iMA call is mBars-y-1, or Bars-0-1, or Bars-1. For each new bar, they are putting the value at bar 0 into the last position of the array.

It's not clear to me why they use the iMA call. It's a 1 period SMA, which is the same as the Price (Open[],Close[], High[],Low[]). I guess that's an easy way to handle the shift, and to include the composite prices (Typical, Weighted Close, etc), but it seems expensive computationally.

George
garyfritz

Re: lowPass filter

Post by garyfritz »

Ahh, I see. Thanks George. And then they reverse it back to "forwards" when they copy mMA[] / mUp[] / mDn[] to MA[] / Up[] / Dn[] (the actual buffers).

I've wondered about the use of iMA(), too. I assumed it was mostly to handle the composite prices. Close[] could handle the shift, but I assume it's actually a call to iClose(), which probably isn't that much cheaper than a 1-long iMA.
Dewey McG
Trader
Posts: 435
Joined: Sat Nov 26, 2011 4:20 pm
Location: Tampa FL

Re: lowPass filter

Post by Dewey McG »

Thanks everyone. Here I am thinking this was a simple request and it is much more complicated.

In actual fact, I was planning on using it in an EA (or EA's) and being able to apply this to the bar highs or lows as in the Zorro code I posted under Zorro before.The relevant part is:



while(asset(loop("EUR/USD","AUD/USD","USD/CHF")))
{
var Period = optimize(5,3,15);
var EMA5H = LowPass(series(priceHigh()),3*Period);
var EMA5L = LowPass(series(priceLow()),3*Period);

Stop = (HH(2) - LL(2)) * optimize(1,0.5,5);

if(priceOpen() > EMA5H && priceClose() < EMA5H && priceLow() > EMA5L)
enterShort();
else if(priceOpen() < EMA5L && priceClose() > EMA5L && priceHigh() < EMA5H)
enterLong();
}
}

I was hoping I could program an EA if I had a lowPass filter to do the same.
User avatar
gaheitman
Trader
Posts: 655
Joined: Tue Nov 15, 2011 10:55 pm
Location: Richmond, VA, US

Re: lowPass filter

Post by gaheitman »

Dewey McG wrote:Thanks everyone. Here I am thinking this was a simple request and it is much more complicated.

In actual fact, I was planning on using it in an EA (or EA's) and being able to apply this to the bar highs or lows as in the Zorro code I posted under Zorro before.The relevant part is:



while(asset(loop("EUR/USD","AUD/USD","USD/CHF")))
{
var Period = optimize(5,3,15);
var EMA5H = LowPass(series(priceHigh()),3*Period);
var EMA5L = LowPass(series(priceLow()),3*Period);

Stop = (HH(2) - LL(2)) * optimize(1,0.5,5);

if(priceOpen() > EMA5H && priceClose() < EMA5H && priceLow() > EMA5L)
enterShort();
else if(priceOpen() < EMA5L && priceClose() > EMA5L && priceHigh() < EMA5H)
enterLong();
}
}

I was hoping I could program an EA if I had a lowPass filter to do the same.
You can call the AllAverages indicator and tell it that you want to use high and then low. It's two calls to iCustom, but depending on the time frame you intend to trade that may not matter.

George
Post Reply

Return to “Indicators”