PureBytes Links
Trading Reference Links
|
[This is an update/bug fix to my original post. Moondays was failing
in certain cases because Tradestation's "mod" function doesn't
handle negative numbers in a methematically correct way. A new
user function, Modulus is introduced to work around that problem.
Thanks to Frank Chin for his help in beta testing these
functions, and Clyde Lee for pointing out the problem in the
calculation of the mod function.]
Traders, find below an Easy Language implementaiton of a calculation
that approximates the phase of the moon, and an associated indicator
and system. This calculation isn't as accurate as the method used
by the authors of the TAS&C article, but has the advantages of being
simple and implemented completely in EL.
The Moonphase indicator is useful for giving a visual cue as to
where the market is in the current lunar cycle, and might be combined
with other indicators such as momemtum, or RSI to produce a useful
system.
Have fun with the code, and if you find any problems, or have
suggestions for improvement, I'd like to hear from you. If
you want to avoid the cut/paste exercise, pick up the
EL archive at ftp://www.intrepid.com/pub/gary/MOON.ELA
howl on,
- Gary
{
Function Modulus - this function properly implements the
modulus function, esp. for negative numbers. The Tradestation
"mod" function does not obey the well-accepted mathematical
definition of modulus, and this function makes up for that.
Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
No restrictions on use/copying. No warranties, expressed/implied.
}
inputs: x(numericsimple), y(numericsimple);
if x*y > 0 then Modulus = mod(x, y)
else Modulus = mod(x,y) + y;
{
Function Moondays returns the number of days since a new moon.
The values returned range between 0 and 29.
(0 = new, and 15 is a full moon to +/- 2 day accuracy.)
Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
No restrictions on use/copying. No warranties, expressed/implied.
This code uses an approximation described in the the "Astro FAQ";
summarized below:
Subject: C.11 How do I calculate the phase of the moon?
Author: Bill Jefferys <bill@xxxxxxxxxxxxxxxxxxx>
John Horton Conway (the Princeton mathematician who is responsible for
"the Game of Life") wrote a book with Guy and Berlekamp, _Winning
Ways_, that describes in Volume 2 a number of useful calendrical
rules. One of these is an easy "in your head" algorithm for
calculating the phase of the Moon, good to a day or better depending
on whether you use his refinements or not.
In the 20th century, calculate the remainder upon dividing the
last two digits of the year by 19; if greater than 9, subtract
19 from this to get a number between -9 and 9.
Multiply the result by 11 and reduce modulo 30 to obtain a
number between -29 and +29.
Add the day of the month and the number of the month (except
for Jan and Feb use 3 and 4 for the month number instead of
1 and 2).
Subtract 4.
Reduce modulo 30 to get a number between 0 and 29. This is
the age of the Moon.
Example: What was the phase of the Moon on D-Day (June 6,
1944)?
Answer: 44/19=2 remainder 6.
6*11=66, reduce modulo 30 to get 6.
Add 6+6 to this and subtract 4: 6+6+6-4=14; the Moon was (nearly)
full. I understand that the planners of D-day did care about the phase
of the Moon, either because of illumination or because of tides. I
think that Don Olsen recently discussed this in _Sky and Telescope_
(within the past several years).
In the 21st century use -8.3 days instead of -4 for the last number.
Conway also gives refinements for the leap year cycle and also
for the slight variations in the lengths of months; what I have
given should be good to +/- a day or so.
}
inputs: dt(numericsimple);
variables: x1(0), x2(0), x3(0), x4(0);
x1 = Modulus(year(dt), 19);
if x1 > 9 then x1 = x1 - 19;
x2 = Modulus(x1 * 11, 30);
x3 = month(dt);
if month(dt) < 3 then x3 = x3 + 2;
x4 = x2 + dayofmonth(dt) + x3 - 4;
Moondays = Modulus(x4, 30);
{
Indicator Moonphase, returns a value between 0..100, that
indicates (approximately) the fullness of the moon, where
0 is a new moon, and 100 is a full moon. This indicator
calls the Moondays function, and is accurate to +/- 2 days.
Accepts an input, offset, which should be in the range -14..14.
Generally, you will not need to change the offset value, unless
for example, you want the display to agree with the offset
value used by Moontrade.
Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
No restrictions on use/copying. No warranties, expressed/implied.
}
input: offset(0);
variables: dt(0), phase(0), mday(0);
dt = juliantodate(datetojulian(date) + offset);
mday = Moondays(dt);
phase = 100*( mday / 15);
if phase > 100 then phase = 200 - phase;
plot1(phase, "moon phase");
{
System Moontrade - buy the new moon, and sell the full moon.
Accepts an input, offset, which should be in the range -14..14.
If the offset is +1, then the system buys at the open of the
day of a new moon and sells at the open on the day of the full moon.
Try optimizing the 'offset' (using a range -14..14 in steps
of 1), or changing the system to only buy the new moon and
go flat on the full moon, when trading decidedly bullish
equity indexes.
Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
No restrictions on use/copying. No warranties, expressed/implied.
}
input: offset(0);
variables: dt(0), dtnxt(0), mday(0), mdaynxt(0);
variables: new_moon(true), full_moon(false);
dt = juliantodate(datetojulian(date) + offset);
dtnxt = juliantodate(datetojulian(date Tomorrow) + offset);
mday = Moondays(dt);
mdaynxt = Moondays(dtnxt);
new_moon = mdaynxt < mday;
full_moon = mdaynxt >= 15 and mday < 15;
if new_moon then buy at market;
if full_moon then sell at market;
-- end --
--
--
| Gary Funck, Intrepid Technology, gary@xxxxxxxxxxxx, (415) 964-8135
|