logo
Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Lloyd_au  
#1 Posted : Wednesday, April 16, 2014 9:18:07 AM(UTC)
Lloyd_au

Rank: Newbie

Groups: Registered, Registered Users
Joined: 1/17/2014(UTC)
Posts: 5

Hi guys.
I have recently taken an interest in BarsSince thanks to John Ehlers. I really should place this in an Ehlers thread I suppose, but anyway.

This is an alternative to setting up hardcoded data from an excel thing. This is just plonking it onto a pre-existing chart with maybe a thousand or much less data points (depends on the 0.993), which are irrelevant for this exercise.

This can be done in Excel. Excel is radians, so whenever there is 180, make it Pi(), or if 360, 2*Pi(). Etc. You'll work it out hopefully without too much angst and the skinning of innocent cats. My preferred platform for doing these acrobatics is Excel, so I hope this works. I think it does, and I am open to suggestions for improvement.
I first set up a theoretical "chirped" sinewave, b, on an existing chart. Whatever. Could be the daily price of eggs.

Chirped cycle
a:=180+.993*PREV;
b:=100*Sin(a);
d:=360/(a-Ref(a,-1));
b
The .993 could be an input, and is very sensitive.
Then in another window measuring the cycle, d. Same code, different indicator. This is accurate (analogue). You may call it boring.
a:=180+.993*PREV;
b:=100*Sin(a);
d:=360/(a-Ref(a,-1));
d
Now I wish to measure the sinewave cycle using BarsSince. In another window, different indicator.
x:=If((Fml("chirped cycle")>0 AND Ref(Fml("chirped cycle"),-1)<0),1,0);
y:=BarsSince(x=1);
y
which creates a sawtooth visual pattern which can then be further coded. I call it Adelaide.
It is kinda fun! Small things amuse small minds I guess.
This lags the actual increasing cycle length as a linear function of actual cycle length, d. This can be calculated exactly in this deterministic theoretical example (not to be confused with real world non stationary noisy cycles) but that is not my point.

BarsSince is pretty cool.

There are many other applications, this is merely one, as most people who have walked on the dark side of BarsSince know - like something of a spiritual epiphany..
Should this have been done before on this forum my apologies - these things have been done before, it is just I have never really seen the code.

I hope this is OK as my first post.


wabbit  
#2 Posted : Wednesday, April 16, 2014 6:24:32 PM(UTC)
wabbit

Rank: Advanced Member

Groups: Registered, Registered Users, Subscribers, Unverified Users
Joined: 10/28/2004(UTC)
Posts: 3,111
Location: Perth, Western Australia

Was thanked: 16 time(s) in 16 post(s)
Lloyd_au wrote:
Code:
{Chirped cycle}
a:=180+.993*PREV;
b:=100*Sin(a);
d:=360/(a-Ref(a,-1));
b

The value of 'a' will increase by a smaller and smaller amount over time, so eventually at some point, the difference between one value and the next will be less than the floating point threshold and your 'd' variable will throw DBZ errors. On my machine, that threshold of change is approximately 0.00195 To fix:
Code:

d:=360/Max(a-Ref(a,-1),0.00195);


There's little point in scalar multiplying 'b' by 100, actually, over multiplying things in MS with its limited floating point operations induces errors so is best avoided whenever possible.

Lloyd_au wrote:
Now I wish to measure the sinewave cycle using BarsSince. In another window, different indicator.
Code:

x:=If((Fml("chirped cycle")>0 AND Ref(Fml("chirped cycle"),-1)<0),1,0);
y:=BarsSince(x=1);
y

which creates a sawtooth visual pattern which can then be further coded. I call it Adelaide.

...

This lags the actual increasing cycle length as a linear function of actual cycle length, d. This can be calculated exactly in this deterministic theoretical example (not to be confused with real world non stationary noisy cycles) but that is not my point.

You don't need to If(x,1,0) as MS does this Boolean operation for you.

For the sake of speed, you should avoid making multiple Fml() calls, just call it once and store its value in a variable. Sometimes, it's faster just to have MS recompute the values that would have been called; there's always a cost to using PREVs, Fml() and FmlVar() calls which have to be balanced.

As the 'thing' you are measuring is a sinusoid, measuring the 'distance' between crossings of the x-axis (y=zero) will only give you the half-cycle length. If you want the full cycle, you measure between three zero crossings, or between two points when the sinusoid is at its minima or maxima; this reduces the number of operations required, in most other programming environments, but it's actually HARDER to do in MS!

Lloyd_au wrote:
It is kinda fun! Small things amuse small minds I guess.

Over the years, I've used MS to plot all sorts of "other" functions, such as oscillations in a suspension bridge, angles of refraction of light through prisms etc. It's not hard to use Excel/NotePad etc to create a datafile for MS with the maximum 65500 bars to be able to plot all sorts of things.

Lloyd_au wrote:
BarsSince is pretty cool.
There are many other applications, this is merely one, as most people who have walked on the dark side of BarsSince know - like something of a spiritual epiphany..

Yes, fun can be had using the basic MS formula language.

Lloyd_au  
#3 Posted : Wednesday, April 16, 2014 7:59:15 PM(UTC)
Lloyd_au

Rank: Newbie

Groups: Registered, Registered Users
Joined: 1/17/2014(UTC)
Posts: 5

Thanks Mr Wabbit, much appreciated. I shall ponder. Excel is clearly my preferred platform; I was transcribing it the best I could into MetaStock after discovering (or remembering what I had forgotten) BarsSince. These things are second nature to me in Excel.

If you take the measurement of the day before the saw tooth goes to zero, it approximates, with a lag that may be adjusted for in this deterministic example by means of a simple linear function, the full cycle. Not half cycle, unless I am missing something, or our definitions of what is a full cycle differ - which is possible. The saw-tooth thing only happens at 360 degrees on this ideal sinewave. I don't have it in front of me right now.

I am really only interested in cycles less than about 50 - after that (and even much before) the noise in real life swamps the increasingly small increments unless you can code Geortzel or even better the Hilbert Huang transform.

Anyway, if nothing else, I hope this helps with people wanting to set up a "chirped" sinewave in Excel (or MS, although I am not sure how to do any real analysis in MS - after doing my analysis in Excel I then plonk it into MS) with corresponding measure of a smooth continuous cycle length. I find this theoretical construct to be valuable whenever confronted with a new holy grail equation to test for lag or lead, amplitude, what is being filtered and where etc.
wabbit  
#4 Posted : Wednesday, April 16, 2014 8:54:07 PM(UTC)
wabbit

Rank: Advanced Member

Groups: Registered, Registered Users, Subscribers, Unverified Users
Joined: 10/28/2004(UTC)
Posts: 3,111
Location: Perth, Western Australia

Was thanked: 16 time(s) in 16 post(s)
Your initial code reminded me of something, but it took me a little while to remember what it was and then more time again to find some work I messed around with ages ago!

Your initial code got me thinking of some old control theory.

Code:

a:=0.993; {0<a<=1.0}
z:=1;

{error check}
a:=max(min(a,1),0.00001);

x:=Cum(1)-1;
n:=Cum(Exp(x * Log(a)));

b:=z*360/LastValue(n);

{plot}
Sin(b*n);


where:
a - is the reaction
z - oscillations until "steady state" (which is never attained)
x - is incrementation along the time axis
n - replaces your PREV function for the recursion

Change values for 'a' and 'z' and see what happens.

[edit] Note: 'a' really only makes any sense, [0.99 <= a <= 1.0] so messing around with values outside this range is just wasting time.

You can have some funky fun (and highlight the rounding/display errors in MS) if you replace the line for 'b' with :
Code:

b:=x*360/LastValue(n);

Zoom in and scroll along...

It's not BarsSince() but it's interesting, to me!


BTW, the Exp(Log()) is not much faster that PREV, it's a personal preference to avoid PREV whenever I can.

Lloyd_au  
#5 Posted : Thursday, May 8, 2014 1:04:32 AM(UTC)
Lloyd_au

Rank: Newbie

Groups: Registered, Registered Users
Joined: 1/17/2014(UTC)
Posts: 5

Yeah so I thought about this a bit more over a glass of the finest wine available to humanity and my 3 remaining neurons decided it needed closure. I still use PREV. Apologies.
We have chirped cycle -
a:=180+.992*PREV;
b:=100*Sin(a); {I maintain the 100 because my eyes glaze over and become more foggy than usual with decimals}
d:=360/(a-Ref(a,-1));
b
Newish formula -
a:=Fml("chirped cycle");
x:=If(a>0 AND Ref(a,-1)<0,1,0); {technically, should allow if a=0}
x1:=BarsSince(x=1);
x2:=If(x1<Ref(x1,-1) AND Ref(x1,-1)>Ref(x1,-2),Ref(x1,-1),PREV);
y:=If(a<0 AND Ref(a,-1)>0,1,0);
y1:=BarsSince(y=1);
y2:=If(y1<Ref(y1,-1) AND Ref(y1,-1)>Ref(y1,-2),Ref(y1,-1),PREV);
(x2+y2)/2
(Crossing paws that copy and paste works). It roughly follows "d", the perfect cycle length, in chirped cycle.

Now - I could, over further glasses of the finest wine available to humanity, rant about how to actually maybe use this in a meaningful manner in the markets and understand its limitations, with examples, but maybe it is not appropriate on this thread - purely fun theoretical stationary data up to now illustrating BarsSince.

Next project - currently scribbled illegibly on a wine stained napkin - is to derive a true median over an array - stock MS formula is not true median. It isn't pretty, even for just a handful of numbers.
wabbit  
#6 Posted : Thursday, May 8, 2014 3:13:31 AM(UTC)
wabbit

Rank: Advanced Member

Groups: Registered, Registered Users, Subscribers, Unverified Users
Joined: 10/28/2004(UTC)
Posts: 3,111
Location: Perth, Western Australia

Was thanked: 16 time(s) in 16 post(s)
Your chirped cycle code throws DBZ errors. Again, you don't need to do the Boolean If() operations as MS will that for you. It's prudent to always check for a complete definition for crossing events. You can get rid of the slow PREV functions too; replace them with ValueWhen():

Code:

a:=Fml("chirped cycle");
 
x:=a>0 AND Ref(a>0,-1)=0; {crossing event}
x1:=BarsSince(x);
x2:=ValueWhen(1,x1=0,Ref(x1,-1));

y:=a<0 AND Ref(a<0,-1)=0; {crossing event}
y1:=BarsSince(y);
y2:=ValueWhen(1,y1=0,Ref(y1,-1));

{plot}
(x2+y2)/2;


Similar results can be found using Cum(1) instead of BarsSince(), in a pseudo count-and-reset function:

Code:

a:=Fml("chirped cycle");

init:=Cum(IsDefined(a))=1;
counter:=Cum(1);

x:=a>0 AND Ref(a>0,-1)=0; {crossing event}
x:=ValueWhen(1,x,counter)-ValueWhen(2,x OR init,counter)-1;

y:=a<0 AND Ref(a<0,-1)=0; {crossing event}
y:=ValueWhen(1,y,counter)-ValueWhen(2,y OR init,counter)-1;

{plot}
(x+y)/2;


Enjoy!

As for finding the median (or any percentile) of a data array of any useful length, you'll have to use the MDK and perform the sort and return outside MS.


Lloyd_au  
#7 Posted : Thursday, May 8, 2014 7:13:28 AM(UTC)
Lloyd_au

Rank: Newbie

Groups: Registered, Registered Users
Joined: 1/17/2014(UTC)
Posts: 5

Thankyou for that Mr Wabbit. You inspire me to learn MS code a bit better. I have no idea what MDK is. Should I RTFM? v.8 pro. It has been more years than I care to remember.

So, what I have done is code median into Excel, and simply attempt to transfer to MS. There is no sorting, or maybe there is - it is logical, I think. Promise - no PREV -:)

I shall take your wisdom into consideration as there are a bunch of "if" things and I will share the code in the fullness of time.

I have also coded the Vicsek measure of the fractal dimension index in basic MS code. Will share that, too, with its obvious limitations for MS. It is not the best measure - the best algorithms require higher maths than basic MS can cope with. Better than a stick in the eye though. Not to be taken too seriously.
wabbit  
#8 Posted : Thursday, May 8, 2014 7:40:49 AM(UTC)
wabbit

Rank: Advanced Member

Groups: Registered, Registered Users, Subscribers, Unverified Users
Joined: 10/28/2004(UTC)
Posts: 3,111
Location: Perth, Western Australia

Was thanked: 16 time(s) in 16 post(s)
The MDK is the MetaStock Developers Kit : https://www.metastock.com/partners/developers.aspx Win32 DLLs which can be called from MS using the ExtFml() function. Because you're outside MS, you can write your code in any language capable of being compiled as a Win32 DLL, such as C/C++, Delphi Pascal and PowerBasic.

Median outside MS is simple; sort the data and then select the "middle" value; it's how MEDIAN in Excel works too. Doing it within the limitations of the MS scripting language, you're limited by the 2500 character limit, no internal loops, no data structures etc... hence any "higher maths" is much easier to achieve elsewhere.
Lloyd_au  
#9 Posted : Friday, May 9, 2014 7:24:05 AM(UTC)
Lloyd_au

Rank: Newbie

Groups: Registered, Registered Users
Joined: 1/17/2014(UTC)
Posts: 5

Being a junior member I am not confident about opening a new thread.

This is not difficult code, in my opinion. Just pretty tricky to get right - I have seen some versions which are wrong.. Tradestation published its code in TASC a few years ago - Easylanguage has an iterative technique or something like that. Easy.

So, this is the fractal dimension index originally proposed by a bloke named Vicsek. I did a google and cannot find the original article!! Sheesh. I have it somewhere. He did a bit of a code thing in the appendix which was clear as mud to me. Anyway, it is pretty clunky in MS, as everyone knows by now I am pretty basic when it comes to MS code. I understand the maths, and code it to the best of my abilities.

Now this is just for 15 days which is too short. Want more? I use 42, because that is the answer. Very scientific. Need to do another bunch and link it/them with fml.

Hey look, no PREV! :-)

pd:=15;
x:=C; {this is the subject of experimentation and is quite important if you think about things for more than a nanosecond}
r:=HHV(H,pd)-LLV(L,pd); {serious issue with this is spikes. Nobody seems to address it, sigh}
a1:=Sqrt(Pwr((Ref(x,-0)-Ref(x,-1))/r,2)+1/Pwr(pd,2));
a2:=Sqrt(Pwr((Ref(x,-1)-Ref(x,-2))/r,2)+1/Pwr(pd,2));
a3:=Sqrt(Pwr((Ref(x,-2)-Ref(x,-3))/r,2)+1/Pwr(pd,2));
a4:=Sqrt(Pwr((Ref(x,-3)-Ref(x,-4))/r,2)+1/Pwr(pd,2));
a5:=Sqrt(Pwr((Ref(x,-4)-Ref(x,-5))/r,2)+1/Pwr(pd,2));
a6:=Sqrt(Pwr((Ref(x,-5)-Ref(x,-6))/r,2)+1/Pwr(pd,2));
a7:=Sqrt(Pwr((Ref(x,-6)-Ref(x,-7))/r,2)+1/Pwr(pd,2));
a8:=Sqrt(Pwr((Ref(x,-7)-Ref(x,-8))/r,2)+1/Pwr(pd,2));
a9:=Sqrt(Pwr((Ref(x,-8)-Ref(x,-9))/r,2)+1/Pwr(pd,2));
a10:=Sqrt(Pwr((Ref(x,-9)-Ref(x,-10))/r,2)+1/Pwr(pd,2));
a11:=Sqrt(Pwr((Ref(x,-10)-Ref(x,-11))/r,2)+1/Pwr(pd,2));
a12:=Sqrt(Pwr((Ref(x,-11)-Ref(x,-12))/r,2)+1/Pwr(pd,2));
a13:=Sqrt(Pwr((Ref(x,-12)-Ref(x,-13))/r,2)+1/Pwr(pd,2));
a14:=Sqrt(Pwr((Ref(x,-13)-Ref(x,-14))/r,2)+1/Pwr(pd,2));
a15:=Sqrt(Pwr((Ref(x,-14)-Ref(x,-15))/r,2)+1/Pwr(pd,2));

d1:=1+(a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15)+Log(2))/Log(2*(pd-1));
1.5;d1

Crossing paws, as always.

Edit - in theory, the FDI ought to vary between 1 and 2. 1.5 is random Brownian. For those who test this code in Excel will find that it has lower and upper limits narrower than this. Subsequent PhD geeks have addressed this with some success, but wow, beyond basic MS code.
Users browsing this topic
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.