lowPass filter
-
Dewey McG
- Trader
- Posts: 435
- Joined: Sat Nov 26, 2011 4:20 pm
- Location: Tampa FL
lowPass filter
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.
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
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.
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.
- gaheitman
- Trader
- Posts: 655
- Joined: Tue Nov 15, 2011 10:55 pm
- Location: Richmond, VA, US
Re: lowPass filter
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?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.
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
-
dietcoke
- Trader
- Posts: 162
- Joined: Tue Nov 15, 2011 9:59 pm
Re: lowPass filter
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?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.![]()
The pertinent loop:GeorgeCode: 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]; }
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;- gaheitman
- Trader
- Posts: 655
- Joined: Tue Nov 15, 2011 10:55 pm
- Location: Richmond, VA, US
Re: lowPass filter
Wow, you remembered that? Impressive.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:GeorgeCode: 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]; }
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;
George
-
garyfritz
Re: lowPass filter
That IS impressive! 
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.
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.
- gaheitman
- Trader
- Posts: 655
- Joined: Tue Nov 15, 2011 10:55 pm
- Location: Richmond, VA, US
Re: lowPass filter
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).garyfritz wrote:That IS impressive!
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.
This line:
Code: Select all
aPrice[y] = iMA(NULL,TimeFrame,1,MA_Shift,0,Price,mBars-y-1); 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
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.
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
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.
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.
- gaheitman
- Trader
- Posts: 655
- Joined: Tue Nov 15, 2011 10:55 pm
- Location: Richmond, VA, US
Re: lowPass filter
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.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.
George
