Rank: Advanced Member
Groups: Registered, Registered Users Joined: 4/24/2005(UTC) Posts: 77 Location: Canada
|
Many of MS users bent their head against the wall trying to code some recursive filters that are so abundant in the trading literature.
I will split this post in 2 subjects:
1) The "+PREV-PREV" construct explanation
If one of the MSFL experts can provide some details about how this construct works and few examples about what can be achieved with it.
(one example is from the Equis Customer Zone web site "Tips from TASC Magazine" = Ehlers filters)
2) Recursive Equations
An example about the CORRECT way to implement this type of recursive code:
f:=a*Typ()+b*f[1]+c*f[2]+d*f[3]+e*f[4]; where f[1],f[2],f[3],f[4] are the referenced function values 1,2,3 and 4 bars ago.
(It's clear that PREV=f[1] but I believe the Ref(PREV,-1) is not equivalent to f[2]).
I am sure this post will provide an extremely valuable answer for the MS community, so the experts of MSFL that can find a solution for it will be highly praised.
Guara
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 1/19/2005(UTC) Posts: 1,065 Location: Koh Pha-Ngan, Earth
Was thanked: 2 time(s) in 2 post(s)
|
1) LastValue(data array +PREV-PREV)
This is the equivalent to a mythical CurrentValue(data array) function.
The +Prev function overrides the LastValue() function, and returns the previous value of LastValue(data array).
The -Prev function also overrides the LastValue() function, and neutralizes the +PREV function.
The result is a "locked" data array to the current value.
Example:
[code:1:0b70d86988]
==============
CCI - Standard
==============
---8<------------------
pds:=Input("CCI periods",1,2600,14);
x:=Typical();
y:=Mov(x,pds,S);
z:=Mov(Abs(x-LastValue(y+PREV-PREV)),pds,S);
ZZI:=(x-y)/(z*0.015);
ZZI
---8<------------------
[/code:1:0b70d86988]
In the above example, LastValue(y+PREV-PREV) locks the Mov(x,14,S) to the current bar's value, allowing it to be deducted from each of Typical()'s previous 14 values without shifting.
2)
PREV and Ref(data array,-1) are very different.
From MetaStock's Help:
"The PREV constant allows you to create self-referencing formulas. A self referencing formula is one that is able to reference the "previous" period's value of itself."
jose '-)
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers Joined: 9/8/2004(UTC) Posts: 2,266
Was thanked: 1 time(s) in 1 post(s)
|
Quote:The result is a "locked" data array to the current value.
I don't think I would use the word "locked" :lol: in reality what happens by using +Prev-Prev is that you are forcing the software to start its calculations for each bar from the first bar of data available to the current bar ... The lastvalue fools the software into believing the array is constant. That's why it works and that is why it makes calculations so much slower ...
I honestly do not believe it was intended by Equis, I just think they were lucky to find this ...
Patrick :mrgreen:
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 1/19/2005(UTC) Posts: 1,065 Location: Koh Pha-Ngan, Earth
Was thanked: 2 time(s) in 2 post(s)
|
Patrick wrote:The lastvalue fools the software into believing the array is constant.
The LastValue() function has fooled more than just software over the years... ;)
jose '-)
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 4/24/2005(UTC) Posts: 77 Location: Canada
|
Thank you Jose and Patrick for your answers.
1) The "+PREV-PREV" construct
Here is my sequence of tests for the "+PREV-PREV" combination:
z1:=LastValue(C+PREV-PREV);
z2:=C;
z1==z2 at any point in the chart.
The 2nd test has proved also that the following 2 equation generate exactly the same output, where "x" and "y" are listed in your CCI formula:
z1:=Abs(x-LastValue(y+PREV-PREV));
z2:=Abs(x-y);
z1==z2 at any point in the chart.
In the 3rd test is where the difference shows up:
z1:=Mov(Abs(x-LastValue(y+PREV-PREV)),pds,S);
z2:=Mov(Abs(x-y),pds,S);
z1<>z2 for almost EVERY point in the chart;
So my conclusion is that the result of the "+PREV-PREV" construct depends on the context in which it is used.
I accept Jose's explanation as a valid one that comes from a very experienced MSFL user, but I must agree that the construct is a very elusive one and its behavior isn't obvious at all.
To recap: z1 in my 3rd test in fact calculates the SMA of an absolute difference between Typ() and its own SMA while its own SMA last bar value is kept CONSTANT for a BACKWARD time period equal to the length of the SMA. This behavior is the result of the "+PREV-PREV" construct in the LastValue function.
The difference between z1 and z2 is that z2 calculates the SMA of the absolute value of the difference for EACH SMA value at EVERY bar, instead of keeping it constant for a BACKWARD time period equal to the SMA length.
Jose please confirm.
2) Recursive equations
Any ideas if this is possible?
Thank you Jose and Patrick for your inputs
Regards
Guara
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 1/19/2005(UTC) Posts: 1,065 Location: Koh Pha-Ngan, Earth
Was thanked: 2 time(s) in 2 post(s)
|
guara_riua wrote:The difference between z1 and z2 is that z2 calculates the SMA of the absolute value of the difference for EACH SMA value at EVERY bar, instead of keeping it constant for a BACKWARD time period equal to the SMA length.
Jose please confirm.
Confirmed. Good explanation. :)
jose '-)
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 6/5/2005(UTC) Posts: 35
|
Here is another example of odd behavior:
ti:= 15;
pr:= MP();
{test 1}
coef:=Sum(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2),ti);
test1 := Sum(coef*pr,ti)/Sum(coef,ti);
coef:=Sum(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2),ti);
{ test2 }
coefA:=(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2));
coef := Sum(coefA,ti);
test2 := Sum(coef*pr,ti)/Sum(coef,ti);
test1;test2;
Once again, the context is different, and so the result is different. There is a divide by zero error, and it plots equal to zero, except for the last bar.
Brad Ulrich
www.thedml.com
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 6/5/2005(UTC) Posts: 35
|
Here is another example of odd behavior, in fact, it is the Ehlers' example from above.
ti:= 15;
pr:= MP();
{test 1}
coef:=Sum(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2),ti);
test1 := Sum(coef*pr,ti)/Sum(coef,ti);
coef:=Sum(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2),ti);
{ test2 }
coefA:=(Power(Ref(LastValue(pr+PREV-PREV)-pr,-1),2));
coef := Sum(coefA,ti);
test2 := Sum(coef*pr,ti)/Sum(coef,ti);
test1;test2;
Once again, the context is different, and so the result is different. There is a divide by zero error, and it plots equal to zero, except for the last bar.
In fact, this bothered me, along with the fact that the code calculated very slowly, so I included the DSquared funciton that is being calculated there in the DML_UTIL.dll that is included with the most recent ASI download (for free).
Here is an example of it:
pr:= MP();
periods := 15;
coef := ExtFml("DML_UTIL.DSQUARED",pr,periods);
filter := Sum(coef*pr,periods) / Sum(coef,periods);
filter;
I wasn't sure if you knew about this Radu...However, this is only a solution to the particular recursive problem, and not a general purpose one.
Regards,
Brad Ulrich
www.thedml.com
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 4/24/2005(UTC) Posts: 77 Location: Canada
|
I finaly got it by myself!
A good example is posted in the "Formula Collection" under the Forum Index or in "Formulae":
- "ITrend by Dr. Ehlers".
In short this is the general equation I was asking about:
f:= A0*Pr + A1*Ref(Pr,-1) + A2*Ref(Pr,-2) + A3*Ref(Pr,-3) + A4*Ref(Pr,-4) +
B0*PREV + B1*Ref(PREV,-1) + B2*Ref(PREV,-2) + B3*Ref(PREV,-3);
where "Pr" is the PRICE type of choice (i.e. OHLC,MP(),TYP(),WC() or a short MA).
But be aware of the computing penalties, especially when you are using this type of equation in simulations!
It's my guess that it can take easily days for just a few hundred tests.
Make sure you have a good CPU fan when you intend to run backtesting with this animal!
This is when the DLL's external functions are coming in handy.
Guara
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users, Subscribers Joined: 7/25/2005(UTC) Posts: 1,042
Was thanked: 57 time(s) in 54 post(s)
|
Guara
Just because a formula has several PREVs in it doesn't mean that they are all necessary. Brad has shown how the problem can be solved by using certain dlls in certain situations. Ehlers DCF can also be written without recourse to a dll, though I admit that the result is neither short nor pretty. A long MFL version is much more friendly than the PREV version for explorations, indicators and the System Tester though.
I can't see how Ax and Bx are constructed so I can't really comment on the PREV heavy example you've just given, but you shouldn't always assume that just because the author used PREVs that they are absolutely necessary. Such is not always the case. Heikin-Ashi code, for example, uses PREV for the open, HaOpen:=(PREV+HaClose)/2, but there are two ways that I know of to write this without PREV or a DLL.
Last year TASC featured a couple of articles on Darvas Boxes by Daryl Guppy, and the second article was accompanied by 10 indicators created by Matthew Ford. I applaud Matthew for his indicators and I'm assure that a number of people have found them intersting and helpful for Darvas-style trading. My point is, though, that the 6 PREVs spread through the indicators are not necessary and can be removed with no impact at all on the function of the code.
Roy
MetaStock Tips & Tools
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 4/24/2005(UTC) Posts: 77 Location: Canada
|
Roy
I don't have your MSFL expertise but the decision to spend the additional time to find a more "efficient" solution to implement the same thing without PREV is very easy for me to make:
- pay a MFSL expert like you or Jose to see if there is a solution at all OR
- wait for a DLL that provides the function
My perception as a "young" trader is that one must spent his valuable time in developing and testing TRADING SYSTEMS, not becoming an MSFL specialist in order to overcome the CRONIC MetaStock Formula Language limitations!
If one has to learn programming or improve his own programming skills, my approach is to go for C++ or Delphi, buy the MDK developer's Kit from Equis and write your own DLL. It's one time learning curve and it will always provide the user with the best solutions.
I have all the respect for you and Jose, don't read me wrong, but personally I don't believe there is any future for the current format of MSFL.
I don't know how others deal with these kind of issues and MSFL limitations, but I will not spend my time banging my head to the walls in trying to find a work around by using what I perceive to be a DEAD LANGUAGE.
As regarding the ITrend solution I've posted, this was done in order to provide an intermediate support for those interested to evaluate the indicator and later on - maybe - to buy it from "The DML" company (the ADSI package).
Regarding my general recursive function formula, all the Ax/Bx are constant coefficients, or have a very simple formula to calculate them using the basic 4 arithmetic operators (+,-,*,/). I have no idea how a RECURSIVE FIXED DSP Filter formula can be re-written without using a self-referencing equation of the original function, or if it's possible at all. These formulas are generated in most cases by using dedicated filter software.
I got my hands onto one of these "wonders" that generates FIR filter coefficients with very efficient attenuation in the cut-off band, but guess what: MetaStock is not able to handle constants with 13-15 digits after the decimal point! Not to mention few hundreds of Ref() instantiations necessary to avoid ther use of IIR filters that have to use PREV!
I know there is a very capable man (Grant Robertson - Product Development Manager) that took on his shoulders a very challenging task that is to bring MetaStock to a competitive level with the other most popular platforms in the industry.
I hope all his efforts and the contribution of dedicated people like you and Jose will make his task easier.
Regards
Guara
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 1/19/2005(UTC) Posts: 1,065 Location: Koh Pha-Ngan, Earth
Was thanked: 2 time(s) in 2 post(s)
|
Guara, it is my experience that the more complex and "scientific/mathematical" a formula becomes, the less useful it is for trading purposes.
I have both MetaStock and AmiBroker, and apart from AB's ability to change variable inputs in real time, I hardly ever bother with AB's ever-increasing complexity.
The markets bear little resemblance to high-resonance-quadruple-pass-recursive-multi-pole-non-linear-cybernetic-quantum-filter indicators.
Complexity tends to inhibit inspiration. Too much time & effort spent on rocket science leads to nowhere in this industry.
MetaStock is a very good blend of user-friendliness and complexity for almost any trading-related task. Believe me, MS is far from "dead".
jose '-)
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 4/24/2005(UTC) Posts: 77 Location: Canada
|
Jose
I appreciate very much your input.
I am inclined to agree with you regarding a complex trading system: I don't believe the more complex the system the better. Quite the opposite.
But to disqualify the advances of science and its increasing capability to provide new models for the trading market I cannot agree with.
I truly believe the more one can read, the larger his understanding grows.
The legendary methods of J.W.Gann, the Fibonacci series of numbers, the revolutionary cycle analysis based methods of J.M.Hurst have proved that mathematics, physics and other scientific domains did and can provide valuable break-through models and solutions for the trading markets.
I am not discounting the occult sciences as well as planetary harmonics, cosmic cycles, other universal forces etc.
I do not intend to open an argumentative session about this matter.
I am just saying that for those technically inclined and willing to use scientific methods in trading, the current MS Formula Language is not the right solution.
On the other hand, there are many solid and classic consistent systems that are not using "high-tech" functions that do provide very wealthy returns to those that taught themselves how to use them, and most importantly how to exercise a solid trading discipline.
For this last mentioned group I agree the MFSL is quite sufficient.
Regards
Guara
|
|
|
|
Rank: Advanced Member
Groups: Registered, Registered Users Joined: 1/19/2005(UTC) Posts: 1,065 Location: Koh Pha-Ngan, Earth
Was thanked: 2 time(s) in 2 post(s)
|
Guara, one needs to take care to differentiate between science, and pseudo-science.
And even when using truly "scientific" methods, the only ones that may work in the markets are based on group/mass psychology and the understanding of market forces, rather than unsuitable and unrelated methods such as used in particle physics for example.
jose '-)
|
|
|
|
Users browsing this topic |
Guest (Hidden)
|
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.